package com.xbongbong.paas.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.outLink.domain.entity.OuterLinkConfigEntity;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DateTypeEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.OuterLinkFilterRemoveAttrEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.factory.OptionFactory;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkDetailPojo;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.handle.AbstractOptionHandle;
import com.xbongbong.paas.help.analysis.data.FormDataCloudCodeDataListAnalysisDataHelp;
import com.xbongbong.paas.log.entity.OutLinkQueryLogEntity;
import com.xbongbong.paas.log.model.OutLinkQueryLogModel;
import com.xbongbong.paas.lowcode.CustomButtonService;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.outerlink.interfaces.PaasOuterLinkConfigService;
import com.xbongbong.paas.pojo.ButtonExtraPojo;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.KeyValuePojo;
import com.xbongbong.paas.pojo.ProductFieldPojo;
import com.xbongbong.paas.pojo.ShareConditionFormatPojo;
import com.xbongbong.paas.pojo.dto.ColumnSetListDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.ColumnSetListVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.pojo.vo.PrePaymentBalanceListVO;
import com.xbongbong.paas.pojo.vo.UserFormPermissionVO;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.UserConfigExplainService;
import com.xbongbong.paas.service.UserConfigService;
import com.xbongbong.paas.service.UserService;
import com.xbongbong.paas.service.team.TeamDataHelp;
import com.xbongbong.paas.service.workflow.trigger.WorkflowFormDataOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.pojo.PermissionTermsPojo;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.explain.FormDataListFormExplainHandleName;
import com.xbongbong.parent.parse.data.FormDataListAnalysisDataHelp;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.custombutton.pojo.dto.CustomButtonListDTO;
import com.xbongbong.pro.custombutton.pojo.vo.CustomButtonListVO;
import com.xbongbong.pro.detailtab.vo.team.TeamListBatchPermissionVO;
import com.xbongbong.pro.domain.entity.ChartCategoryEntity;
import com.xbongbong.pro.domain.entity.LabelEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.SummaryTypeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.lowcode.ButtonTypeEnum;
import com.xbongbong.pro.enums.permission.enums.UpdateProPermissionAliasEnum;
import com.xbongbong.pro.enums.workflow.TriggerEventTypeEnum;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.packageInfo.pojo.vo.BasePackageInfoVO;
import com.xbongbong.pro.permission.pojo.dto.VerifyUpdatePermissionDTO;
import com.xbongbong.pro.product.pojo.dto.FilterAttrOnOffJXCDTO;
import com.xbongbong.pro.statistic.model.ChartCategoryModel;
import com.xbongbong.pro.workorder.pojo.TimeConsumingOutPojo;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderDataEsListVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CommunicatePlanUserEntity;
import com.xbongbong.saas.domain.entity.PaymentTaskUserEntity;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderStageEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.ChildProductFieldEnum;
import com.xbongbong.saas.enums.CreditTemporaryApplyStatusEnum;
import com.xbongbong.saas.enums.ListBatchEnum;
import com.xbongbong.saas.enums.ListBottomButtonEnum;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.ListOptionEnum;
import com.xbongbong.saas.enums.ListOptionTabEnum;
import com.xbongbong.saas.enums.ListTopButtonEnum;
import com.xbongbong.saas.enums.OperatePageEnum;
import com.xbongbong.saas.enums.OutLinkSettingTypeEnum;
import com.xbongbong.saas.enums.OuterLinkTypeEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SaasBatchEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.SaasSubButtonEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.WorkOrderNodeStatusEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CreditTemporaryLimitEnum;
import com.xbongbong.saas.enums.business.InvoiceDistributorEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PaymentTaskEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.SmartReplenishmentEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.product.RefundProductEnum;
import com.xbongbong.saas.help.SaasFormHelp;
import com.xbongbong.saas.help.SaasListHelp;
import com.xbongbong.saas.help.StageHelp;
import com.xbongbong.saas.model.CommunicatePlanUserModel;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.LabelModel;
import com.xbongbong.saas.model.PaymentTaskUserModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.service.CreditLimitService;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.saas.service.KnowledgeDataService;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.service.ProductStockInfoService;
import com.xbongbong.saas.service.ProductWarehouseService;
import com.xbongbong.saas.service.SaasListService;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.UserConfigEnum;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.UserConfigModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.ContractCompareUtil;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workorder.service.WorkOrderBasicService;
import com.xbongbong.workorder.service.WorkOrderStageService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author haibin.zhang
 * @version v1.0
 * @date 2019/5/20 15:36
 * @since v1.0
 */
@Component
public class FormDataListSearchHelp {
    private static final Logger LOG = LoggerFactory.getLogger(FormDataListSearchHelp.class);
    @Resource
    private SaasListHelp saasListHelp;
    @Resource
    private FormDataListAnalysisDataHelp formDataListAnalysisDataHelp;
    @Resource
    private FormDataCloudCodeDataListAnalysisDataHelp formDataCloudCodeDataListAnalysisDataHelp;
    @Resource
    private UserService userService;
    @Resource
    private UserConfigModel userConfigModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private FormDataListFormExplainHandleName formDataListFormExplainHandleName;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private SaasListService saasListService;
    @Resource
    private FormDataListSearchHelp formDataListSearchHelp;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private ProductService productService;
    @Resource
    private UserModel userModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private CommunicatePlanUserModel communicatePlanUserModel;
    @Resource
    private UserConfigService userConfigService;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private FundSetService fundSetService;
    @Resource
    private ProductWarehouseService productWarehouseService;
    @Resource
    private ProductStockInfoService productStockInfoService;
    @Resource
    private CloudCodeHelp cloudCodeHelp;
    @Resource
    private PaymentTaskUserModel paymentTaskUserModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private PaasOuterLinkConfigService outerLinkConfigService;
    @Resource
    private EsHelper esHelper;
    @Resource
    private OptionFactory optionFactory;
    @Resource
    private OutLinkQueryLogModel outLinkQueryLogModel;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private WorkOrderStageService workOrderStageService;
    @Resource
    private WorkOrderBasicService workOrderBasicService;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private SaasFormHelp saasFormHelp;
    @Resource
    private CustomButtonService customButtonService;
    @Resource
    private LabelModel labelModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private CreditLimitService creditLimitService;
    @Resource
    private ChartCategoryModel chartCategoryModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private BusinessListHelp businessListHelp;
    @Resource
    private UserConfigExplainService userConfigExplainService;

    @Resource
    private PackageHelp packageHelp;
    @Resource
    private CompanyModel companyModel;

    @Resource
    private IndexTypeModel indexTypeModel;

    @Resource
    private TeamDataHelp teamDataHelp;
    @Resource
    private KnowledgeDataService knowledgeDataService;
    @Resource
    private StageHelp stageHelp;
    @Resource
    private WorkflowFormDataOperationService workflowFormDataOperationService;
    @Resource
    private ContractCompareUtil contractCompareUtil;
    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;

    /**
     * Description:
     * @param formDataListDTO
     * @return com.xbongbong.pro.formexplain.pojo.HandleExplainPojo
     * @throws
     * @author 魏荣杰
     * @date 2023/4/1 22:54
     * @since
     */
    public HandleExplainPojo handleExplain(FormDataListDTO formDataListDTO) throws XbbException {
        //分组条件
        List<ConditionsEntityExt> groupConditionsList = new ArrayList<>();
        List<List<ConditionsEntityExt>> shouldCondition = new ArrayList<>();
        // 产品
        saasListHelp.selectProductCondition(formDataListDTO.getConditions(),formDataListDTO.getCorpid());
        saasListHelp.packageGroupList(formDataListDTO,groupConditionsList,shouldCondition);
        formDataListDTO.getConditions().addAll(groupConditionsList);
        // 地址查询条件封装
        saasListHelp.addressSearchShouldCondition(formDataListDTO);
//        saasListHelp.addressSearchCondition(formDataListDTO);
        saasListHelp.commonFilter(formDataListDTO);
        //过滤审批中数据
        filterApprovalData(formDataListDTO);
        //过滤应收款中有（老）红冲应收款的数据，针对应收款特地写的一个方法
        formDataListDTO.setShouldConditions(setPaymentIsRed(formDataListDTO));
        //表单获取
        PaasFormEntityExt form = formDataListSearchHelp.getForm(formDataListDTO);
        //解释获取以及处理
        HandleExplainPojo handleExplainPojo = formDataListSearchHelp.handlExplains(formDataListDTO,form);
        handleExplainPojo.setForm(form);
        //默认排序 字段显示
        formDataListSearchHelp.setListColumn(formDataListDTO);

        List<ConditionsEntityExt> permission = new ArrayList<>();
        if (Objects.nonNull(formDataListDTO.getSharePermission()) && CollectionsUtil.isNotEmpty(formDataListDTO.getSharePermission().getPermissionConditions())) {
            // 获取基础数据权限，上层有前置做基础数据权限封装，这边做兼容
            permission = formDataListDTO.getSharePermission().getPermissionConditions();
        }

        // 获取paas的本人及其下属的数据
        List<ConditionsEntityExt> paasPermission = getPaasPermission(formDataListDTO);
        if (CollectionsUtil.isNotEmpty(paasPermission)) {
            permission.addAll(paasPermission);
        }

        // 共享权限的处理
        ShareConditionFormatPojo sharePermission = saasListDataPermissionHelp.getSharePermission(permission, Collections.singletonList(formDataListDTO.getFormId()), formDataListDTO.getLoginUser());
        formDataListDTO.setSharePermission(sharePermission);
//        formDataListDTO.setConditions();
        return handleExplainPojo;
    }

    public PaasFormDataEsListVO getEsList(FormDataListDTO formDataListDTO) throws XbbException{

        HandleExplainPojo handleExplainPojo = handleExplain(formDataListDTO);
        List<FieldAttrEntity> explainList = handleExplainPojo.getExplainList();
        PaasFormEntityExt form = handleExplainPojo.getForm();
        //数据查询
        PaasFormDataEsListVO paasFormDataEsListVO;
        if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WARNING_SEARCH.getCode())) {
            paasFormDataEsListVO = productWarehouseService.warningSearchList(formDataListDTO);
        } else if (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.GUARANTEE_SEARCH.getCode())) {
            paasFormDataEsListVO = productStockInfoService.guaranteeSearchList(formDataListDTO, explainList);
        }  else {
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(formDataListDTO.getCorpid(), formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
            paasFormDataEsListVO = paasFormDataEsModel.list(formDataListDTO, indexTypeEnum);
        }

        paasFormDataEsListVO.setUpdateTime(handleExplainPojo.getUpdateTime());
        paasFormDataEsListVO.setForm(form);
        paasFormDataEsListVO.setHeadList(explainList);
        paasFormDataEsListVO.setExplainMap(formDataListDTO.getExplainMap());
        return paasFormDataEsListVO;
    }

    public PaasFormDataEsListVO getOuterLinkList(FormDataListDTO formDataListDTO,String token) throws XbbException{
        PaasFormDataEsListVO paasFormDataEsListVO = new PaasFormDataEsListVO();
        //表单获取
        PaasFormEntityExt form = formDataListSearchHelp.getForm(formDataListDTO);
        // 处理解释字段
        HandleExplainPojo handleExplainPojo = formDataListSearchHelp.handlOuterLinkExplains(formDataListDTO,form);

        List<FieldAttrEntity> explainList = handleExplainPojo.getExplainList();
        // 里面是有对于condition为空判断，因为这是第一次进来，必须让数据为空，所以要在最前面判断
        // 对于condition的增减必须放在后面
        PaasFormDataEsListVO paasFormDataEsList = new PaasFormDataEsListVO();
        paasFormDataEsList.setUpdateTime(handleExplainPojo.getUpdateTime());
        paasFormDataEsList.setForm(form);
        paasFormDataEsList.setHeadList(explainList);
        if (CollectionsUtil.isEmpty(formDataListDTO.getConditions())) {
            PageHelper pageHelper = new PageHelper(formDataListDTO.getPage(), formDataListDTO.getPageSize());
            pageHelper.setRowsCount(0);
            paasFormDataEsList.setPageHelper(pageHelper);
            return paasFormDataEsList;
        }
        handleCondition(formDataListDTO);
        saasListHelp.addressSearchCondition(formDataListDTO);
        //过滤回款计划中有红冲回款计划的数据，针对回款计划特地写的一个方法
        formDataListDTO.setShouldConditions(setPaymentIsRed(formDataListDTO));
        //过滤审批中数据
        filterApprovalData(formDataListDTO);
        formatListCondition(formDataListDTO);
        WorkOrderDataEsListVO workOrderDataEsListVO = new WorkOrderDataEsListVO();
        if (CollectionsUtil.isNotEmpty(explainList)) {
            Boolean searchSubForm = false;
            List<String> subFiledAttr = new ArrayList<>();
            for (FieldAttrEntity item : explainList) {
                if (Objects.equals(item.getFieldType(), FieldTypeEnum.SUB_FORM.getType())) {
                    searchSubForm = true;
                    subFiledAttr.add(item.getAttr());
                }
            }
            formDataListDTO.setSearchSubForm(searchSubForm);
            formDataListDTO.setSubFieldList(subFiledAttr);
        }
        //数据查询
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
            workOrderDataEsListVO = paasFormDataEsModel.workOrderList(formDataListDTO);
            BeanUtil.copyProperties(workOrderDataEsListVO, paasFormDataEsListVO);
        } else {
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(formDataListDTO.getCorpid(), formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
            paasFormDataEsListVO = paasFormDataEsModel.list(formDataListDTO, indexTypeEnum);
        }
        paasFormDataEsListVO.setUpdateTime(handleExplainPojo.getUpdateTime());
        paasFormDataEsListVO.setForm(form);
        paasFormDataEsListVO.setHeadList(explainList);
        paasFormDataEsListVO.setExplainMap(formDataListDTO.getExplainMap());

        formDataListAnalysisDataHelp.analysisOuterLinkDataList(formDataListDTO, paasFormDataEsListVO);
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())) {
            AbstractOptionHandle abstractOptionHandle = optionFactory.getByBusinessType(formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
            abstractOptionHandle.setOptionsInData(formDataListDTO, paasFormDataEsListVO);
        }

        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
            // 工单列表特殊处理
            handleSpecial(formDataListDTO, workOrderDataEsListVO, paasFormDataEsListVO);
        }

        //金额千份位解析,不放入底层以免移动端多次解析失败 单独拎出来
        formDataListAnalysisDataHelp.analysisAmountOfThousandBits(paasFormDataEsListVO, formDataListDTO.getAnalysisAmountOfThousandBitsWithOriginalValue());
        // 处理日期类型的问题
        handleDateField(paasFormDataEsListVO);

        // 外链查询日志
        String module = XbbRefTypeEnum.getByCode(formDataListDTO.getBusinessType()).getName();
        // 查询链接
        // 查询条件解析
        List<ConditionsEntityExt> conditionsEntityExts = formDataListDTO.getConditions();
        JSONArray jsonArray = new JSONArray();
        if(Objects.nonNull(conditionsEntityExts)){
            conditionsEntityExts.forEach(item -> {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("attr",item.getAttr());
                jsonObject.put("name",item.getName());
                jsonObject.put("value",item.getValue());
                jsonArray.add(jsonObject);
            });
        }
        OutLinkQueryLogEntity outLinkQueryLogEntity = new OutLinkQueryLogEntity(formDataListDTO.getCorpid(), formDataListDTO.getPlatform(),formDataListDTO.getBrowserInfo(),formDataListDTO.getIp(),JSONObject.toJSONString(jsonArray),token,module);
        try {
            outLinkQueryLogModel.insert(outLinkQueryLogEntity);
        } catch (XbbException e) {
            LOG.error("外链查询 添加查询日志出错 : ", e);
        }
        return paasFormDataEsListVO;
    }

    /**
     * 处理移动端外链查询页日期展示问题
     *
     * @param paasFormDataEsListVO
     * @throws
     * @author long.rao
     * @date 2020-09-14 12:15
     */
    private void handleDateField(PaasFormDataEsListVO paasFormDataEsListVO) throws XbbException{
        List<PaasFormDataEntityExt> paasFormDataESList = paasFormDataEsListVO.getPaasFormDataESList();
        List<FieldAttrEntity> explainList = paasFormDataEsListVO.getHeadList();
        Map<String, FieldAttrEntity> fieldAttrEntityMap = BeanUtil.convertListToMap(explainList, "attr");
        for (PaasFormDataEntityExt entityExt : paasFormDataESList) {
            JSONObject data = entityExt.getData();
            Iterator<String> iterator = data.keySet().iterator();
            while (iterator.hasNext()) {
                String key = Objects.toString(iterator.next());
                FieldAttrEntity fieldAttrEntity = fieldAttrEntityMap.get(key);
                if (fieldAttrEntity == null) {
                    continue;
                }
                if (ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
                    JSONArray jsonArray = data.getJSONArray(key) == null ? new JSONArray() : data.getJSONArray(key);
                    JSONArray resultJsonArray = new JSONArray();
                    SubFormPoJo subForm = fieldAttrEntity.getSubForm();
                    List<? extends FieldAttrEntity> items = (subForm == null || subForm.getItems() == null) ? new ArrayList<>() : subForm.getItems();
                    Map<String, FieldAttrEntity> subExplainMap = ExplainUtil.getExplainMapByList(items);

                    for (int i = 0; i < jsonArray.size(); i++) {
                        if (!(jsonArray.get(i) instanceof Map)) {
                            continue;
                        }
                        JSONObject subJsonObject = jsonArray.getJSONObject(i);
                        Iterator subIterator = subJsonObject.keySet().iterator();
                        JSONObject subResult = new JSONObject();
                        while (subIterator.hasNext()) {
                            String subKey = Objects.toString(subIterator.next());
                            FieldAttrEntity subFieldAttrEntity = subExplainMap.get(subKey);
                            if (Objects.nonNull(subFieldAttrEntity) && Objects.equals(subFieldAttrEntity.getFieldType(), FieldTypeEnum.DATETIME.getType())) {
                                try {
                                    // 前端渲染需要正常的时间戳，但是有些时间类型的字段存的是字符串类型的时间戳，比如"1600056577",前端就不会解析，所以这边直接转一遍
                                    Long date = subJsonObject.getLong(subKey);
                                    subResult.put(subKey, date);
                                } catch (Exception e) {
                                }
                            } else {
                                subResult.put(subKey, subJsonObject.get(subKey));
                            }
                        }
                        resultJsonArray.add(subResult);
                    }
                    data.put(key, resultJsonArray);
                } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.DATETIME.getType())) {
                    try {
                        // 前端渲染需要正常的时间戳，但是有些时间类型的字段存的是字符串类型的时间戳，比如"1600056577",前端就不会解析，所以这边直接转一遍
                        Long date = data.getLong(key);
                        if (Objects.equals(fieldAttrEntity.getSaasAttr(), "lastConnectTime")) {
                            Object lastConnectTime = data.get(key);
                            if (Objects.nonNull(lastConnectTime) && lastConnectTime instanceof String) {
                                data.put(key, lastConnectTime);
                                continue;
                            }
                        }
                        data.put(key, date);
                    } catch (Exception e) {
                    }
                }
            }
        }
    }

    /**
     * 处理下拉框
     *
     * @param formDataListDTO
     * @throws
     * @author long.rao
     * @date 2020-08-24 10:10
     */
    private void handleCondition(FormDataListDTO formDataListDTO) {
        List<ConditionsEntityExt> conditions = formDataListDTO.getConditions();
        Map<String, FieldAttrEntity> explainMap = formDataListDTO.getExplainMap();
        Integer businessType = formDataListDTO.getBusinessType();
        Iterator<ConditionsEntityExt> iterator = conditions.iterator();
        while (iterator.hasNext()){
            ConditionsEntityExt conditionsEntityExt = iterator.next();
            Integer fieldType = conditionsEntityExt.getFieldType();
            List<Object> value = conditionsEntityExt.getValue();
            String attr = conditionsEntityExt.getAttr();
            if (Objects.equals(fieldType, FieldTypeEnum.COMBO.getType()) ||
                Objects.equals(fieldType, FieldTypeEnum.RADIO_GROUP.getType()) ||
                    Objects.equals(fieldType, FieldTypeEnum.COMBO_CHECK.getType())) {
                if (CollectionsUtil.isEmpty(value)) {
                    continue;
                }
                FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                if (Objects.nonNull(fieldAttrEntity)) {
                    List<ItemPoJo> items = fieldAttrEntity.getItems();
                    if ( Objects.equals(businessType, XbbRefTypeEnum.PRODUCT.getCode()) && Objects.equals(ProductEnum.UNIT.getAttr(), fieldAttrEntity.getAttr()) ) {
                        try {
                            ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), formDataListDTO.getCorpid());
                            List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
                            BeanUtil.copyPropertiesList(multiItems, items, ItemPoJo.class);
                        } catch (Exception e) {
                            LOG.error("产品多单位解析错误",e);
                        }
                    }
                    for (ItemPoJo itemPoJo : items) {
                        if (Objects.equals(itemPoJo.getIsOther(), BasicConstant.ZERO)) {
                            if (Objects.equals(itemPoJo.getText(), value.get(0))) {
                                // 因为前端回传的是text,筛选的时候需要将他转换为value值取查询
                                conditionsEntityExt.setValue(Collections.singletonList(itemPoJo.getValue()));
                                break;
                            }
                        }
                    }
                } else {
                    // 没有解释，那么是这个字段不可见，把这个筛选项去掉
                    iterator.remove();
                }
            } else if (Objects.equals(fieldType, FieldTypeEnum.LABEL.getType())) {
                FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                if (Objects.nonNull(fieldAttrEntity)) {
                    List<Object> idValue = new ArrayList<>();
                    if (CollectionsUtil.isEmpty(value)) {
                        idValue.add(-1);
                        conditionsEntityExt.setValue(idValue);
                        continue;
                    }
                    String valueStr = value.get(0).toString();
                    if (StringUtil.isEmpty(valueStr, true)) {
                        idValue.add(-1);
                        conditionsEntityExt.setValue(idValue);
                        continue;
                    }
                    List<LabelEntity> byName = labelModel.getByName(valueStr, formDataListDTO.getFormId(), formDataListDTO.getCorpid());
                    if (CollectionsUtil.isEmpty(byName)) {
                        idValue.add(-1);
                        conditionsEntityExt.setValue(idValue);
                        continue;
                    }
                    idValue.add(byName.get(0).getId());
                    conditionsEntityExt.setValue(idValue);
                } else {
                    // 没有解释，那么是这个字段不可见，把这个筛选项去掉
                    iterator.remove();
                }
            }
        }
        if (CollectionsUtil.isEmpty(conditions)) {
            // 如果没有筛选项，那么可能是字段空了，所以直接数据也要为空，兜底操作
            ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
            conditionsEntityExt.setAttr(FieldTypeEnum.DATAID.getAlias());
            conditionsEntityExt.setFieldType(FieldTypeEnum.DATAID.getType());
            conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
            conditionsEntityExt.setValue(Arrays.asList(-1L));
            conditions.add(conditionsEntityExt);
            formDataListDTO.setConditions(conditions);
        }
        formDataListDTO.setConditions(conditions);
    }

    public PaasFormDataEsListVO getEsListSuper(FormDataListDTO formDataListDTO) throws XbbException{
        //分组条件
        String corpid = formDataListDTO.getCorpid();
//        List<ConditionsEntityExt> groupConditionsList = new ArrayList<>();
//        List<List<ConditionsEntityExt>> shouldCondition = new ArrayList<>();
        PaasFormEntityExt paasFormEntity;
        Set<String> linkAttrSet = new HashSet<>();
        if (Objects.nonNull(formDataListDTO.getLinkInfo())) {
            if (Objects.isNull(formDataListDTO.getLinkInfo().getLinkFormId())){
                paasFormEntity = paasFormModel.getByBusinessType(formDataListDTO.getLinkInfo().getLinkBusinessType(),corpid);
            }else {
                paasFormEntity = paasFormModel.getByKey(formDataListDTO.getLinkInfo().getLinkFormId(),corpid);
            }
            formDataListDTO.getLinkInfo().getLinkedAttr().forEach(item -> linkAttrSet.add(item.getAttrName()));
        } else {
            LOG.warn("FormDataListSearchHelp.getEsListSuper", formDataListDTO.getCorpid() + "_" + Objects.toString(formDataListDTO.getBusinessType(), ""));
            paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
        }
        formDataListDTO.setAppId(paasFormEntity.getAppId());
        formDataListDTO.setMenuId(paasFormEntity.getMenuId());
        formDataListDTO.setFormId(paasFormEntity.getId());
        formDataListDTO.setSaasMark(paasFormEntity.getSaasMark());
        formDataListDTO.setBusinessType(formDataListDTO.getLinkInfo().getLinkBusinessType());
//        saasListHelp.packageGroupList(formDataListDTO,groupConditionsList,shouldCondition);
//        formDataListDTO.getConditions().addAll(groupConditionsList);
        saasListHelp.addressSearchCondition(formDataListDTO);
        //过滤审批中数据
        filterApprovalData(formDataListDTO);
//        saasListHelp.productSearchCondition(formDataListDTO.getConditions(),formDataListDTO.getShouldConditions(),formDataListDTO.getCorpid());
        //表单获取
//        PaasFormEntityExt form = formDataListSearchHelp.getForm(formDataListDTO);
        //解释获取以及处理
        HandleExplainPojo handleExplainPojo = formDataListSearchHelp.handlExplains(formDataListDTO,paasFormEntity);
        List<FieldAttrEntity> explainList = handleExplainPojo.getExplainList();
//        if (!linkAttrSet.isEmpty()){
//           Iterator<FieldAttrEntity> iterator = explainList.iterator();
//           while (iterator.hasNext()){
//               FieldAttrEntity fieldAttrEntity = iterator.next();
//               if (!linkAttrSet.contains(fieldAttrEntity.getAttr())){
//                   iterator.remove();
//                   formDataListDTO.getExplainMap().remove(fieldAttrEntity.getAttr());
//               }
//           }
//        }
        //解释获取以及处理
//        Map<String,FieldAttrEntity> secondaryExplainMap = formDataListSearchHelp.secondaryExplains(formDataListDTO);
        //默认排序 字段显示
        formDataListSearchHelp.setListColumn(formDataListDTO);
        // 获取paas的本人及其下属的数据
//        formDataListDTO.setConditions(getPaasPermission(formDataListDTO));
        //模糊查询高级模式
        nameLikeSupprtSet(formDataListDTO);
        formDataListDTO.setSearchSubForm(false);
        //数据查询
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(formDataListDTO.getCorpid(), formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
        PaasFormDataEsListVO paasFormDataEsListVO = paasFormDataEsModel.list(formDataListDTO, indexTypeEnum);
        paasFormDataEsListVO.setForm(paasFormEntity);
        paasFormDataEsListVO.setHeadList(explainList);
        paasFormDataEsListVO.setExplainMap(formDataListDTO.getExplainMap());
        return paasFormDataEsListVO;
    }

    private List<List<ConditionsEntityExt>> setPaymentIsRed(FormDataListDTO formDataListDTO){
        List<List<ConditionsEntityExt>> shoudConditions = formDataListDTO.getShouldConditions();
        List<ConditionsEntityExt> conditions = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.PAYMENT.getCode())){
            return shoudConditions;
        }
        ConditionsEntityExt conditionEqualOne = new ConditionsEntityExt(PaymentEnum.IS_RED.getAttr(), "", FieldTypeEnum.NUM.getType(), ConditionEnum.NOLIKE.getSymbol(), Arrays.asList(1));
        conditions.add(conditionEqualOne);
        shoudConditions.add(conditions);
        return shoudConditions;
    }

    public void nameLikeSupprtSet(FormDataListDTO formDataListDTO) {
        String nameLike = formDataListDTO.getNameLike();
        if (Objects.isNull(nameLike) || nameLike.isEmpty()){
            return;
        }
        String[] strList = nameLike.split(":");
        if (strList.length != 2){
            strList = nameLike.split("：");
            if (strList.length != 2){
                return;
            }
        }
        for (Map.Entry<String,FieldAttrEntity> entry : formDataListDTO.getExplainMap().entrySet()) {
            if (Objects.equals(entry.getValue().getAttrName(),strList[0])) {
                FieldAttrEntity fieldAttrEntity = entry.getValue();
                ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt(fieldAttrEntity.getAttr(), "", fieldAttrEntity.getFieldType(), ConditionEnum.LIKE.getSymbol(), Collections.singletonList(strList[1]));
                formDataListDTO.getConditions().add(conditionsEntityExt);
                formDataListDTO.setNameLike("");
                break;
            }
        }
    }

    /**
     * 获取paas的本人及其下属的数据
     * @param formDataListDTO
     */
    public List<ConditionsEntityExt> getPaasPermission(FormDataListDTO formDataListDTO) {
        List<ConditionsEntityExt> conditions = new ArrayList<>();
        if (Objects.equals(SaasMarkEnum.PAAS.getCode(), formDataListDTO.getSaasMark())) {
            // 获取本人及其下属的数据
            UserVO userVO = formDataListDTO.getLoginUser();
            if (userVO.isAdminOrBoss() || userVO.isMaxDataPermission()) {
                return conditions;
            }
            UserEntity userEntity = new UserEntity();
            BeanUtil.copyProperties(userVO, userEntity);
            Integer dataPermission = userModel.getDataPermission(userEntity);
            List<String> userIdList = userModel.getSubIdListByDataPermission(dataPermission, userVO.getUserId(), formDataListDTO.getCorpid(), BasicConstant.ONE, false);
            userIdList.add(formDataListDTO.getUserId());
            List<Object> userIdIn = new ArrayList<>();
            userIdList.forEach(item->{
                userIdIn.add(item);
            });
            //这边还需要加上paas表单的协同人权限
            ConditionsEntityExt corUserConditionsEntityExt = new ConditionsEntityExt();
            corUserConditionsEntityExt.setAttr(FieldTypeEnum.TEAM_USER.getAlias());
            corUserConditionsEntityExt.setFieldType(FieldTypeEnum.TEAM_USER.getType());
            corUserConditionsEntityExt.setSymbol(ConditionEnum.IN.getSymbol());
            corUserConditionsEntityExt.setValue(userIdIn);
            conditions.add(corUserConditionsEntityExt);
            return conditions;
        }else{
            return formDataListDTO.getConditions();
        }
    }

    /**
     *
     * @param formDataListDTO
     * @param formDataListVO
     * @throws XbbException
     */
    public void webDataAnalysis(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO) throws XbbException {
        saasListHelp.filterSubForm(formDataListVO, formDataListDTO.getExplainMap());
        if (Objects.equals(formDataListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            // 设置列表页操作栏
            saasListHelp.setOption(formDataListVO, formDataListDTO);
            saasListHelp.tempData4Show(formDataListDTO, formDataListVO);
            saasListHelp.analysisSaasDataList4Web(formDataListVO, formDataListDTO.getExplainMap());

            // saas特殊逻辑处理数据（包括特殊处理解释）
            saasListHelp.handleEsData4Show(formDataListDTO, formDataListVO);
            // 只存数据库未存es数据处理
            saasListHelp.setOnlyDBData(formDataListDTO, formDataListVO);
        }
        // 上述渲染勿动顺序
        // web端逻辑，主要处理下关于关联数据，用户，部门数据回显的问题
        formDataListAnalysisDataHelp.analysisDataList(formDataListDTO, formDataListVO);
        saasListHelp.handleCategory(formDataListDTO, formDataListVO);

        //web端金额千份位解析,不放入底层以免移动端多次解析失败 单独拎出来
        formDataListAnalysisDataHelp.analysisAmountOfThousandBits(formDataListVO, formDataListDTO.getAnalysisAmountOfThousandBitsWithOriginalValue());
        //红冲合同的计划收款金额、未收金额、坏账金额默认值情况下为0 为了保持和saas以前的一样 这里要改成 --
//        formDataListAnalysisDataHelp.redPaymentShowHandle(formDataListVO);
        // 处理列表页字段排序
        explainFieldSort(formDataListDTO, formDataListVO);
    }


    /**
     * @Author mingliang
     * @Description 泳道视图用，不需要列表视图的排序
     * @Date 2022/1/10 10:19
     * @param formDataListDTO
     * @param formDataListVO
     **/
    public void webDataAnalysisByLane(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO) throws XbbException {
        saasListHelp.filterSubForm(formDataListVO, formDataListDTO.getExplainMap());
        if (Objects.equals(formDataListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            // 设置列表页操作栏
            saasListHelp.setOption(formDataListVO, formDataListDTO);
            saasListHelp.tempData4Show(formDataListDTO, formDataListVO);
            saasListHelp.analysisSaasDataList4Web(formDataListVO, formDataListDTO.getExplainMap());

            // saas特殊逻辑处理数据（包括特殊处理解释）
            saasListHelp.handleEsData4Show(formDataListDTO, formDataListVO);
        }
        // 上述渲染勿动顺序
        // web端逻辑，主要处理下关于关联数据，用户，部门数据回显的问题
        formDataListAnalysisDataHelp.analysisDataList(formDataListDTO, formDataListVO);
        saasListHelp.handleCategory(formDataListDTO, formDataListVO);

        //web端金额千份位解析,不放入底层以免移动端多次解析失败 单独拎出来
        formDataListAnalysisDataHelp.analysisAmountOfThousandBits(formDataListVO, formDataListDTO.getAnalysisAmountOfThousandBitsWithOriginalValue());
    }

    /**
     *
     * @param formDataListDTO
     * @param formDataListVO
     * @throws XbbException
     */
    public void cloudCodeDataAnalysis(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO) throws XbbException {
        // 上述渲染勿动顺序
        // web端逻辑，主要处理下关于关联数据，用户，部门数据回显的问题
        formDataCloudCodeDataListAnalysisDataHelp.analysisDataList(formDataListDTO, formDataListVO);
        saasListHelp.handleCategory(formDataListDTO, formDataListVO);

        //web端金额千份位解析,不放入底层以免移动端多次解析失败 单独拎出来
        formDataListAnalysisDataHelp.analysisAmountOfThousandBits(formDataListVO, formDataListDTO.getAnalysisAmountOfThousandBitsWithOriginalValue());
        //红冲合同的计划收款金额、未收金额、坏账金额默认值情况下为0 为了保持和saas以前的一样 这里要改成 --
//        formDataListAnalysisDataHelp.redPaymentShowHandle(formDataListVO);
        // 处理列表页字段排序
        explainFieldSort(formDataListDTO, formDataListVO);
    }

    /**
     * 移动端
     * @param formDataListDTO 列表页入参
     * @param formDataListVO 列表页回参
     * @return 摘要和标题的封装会新初始化一个对象，保险起见
     * @throws XbbException
     */
    public PaasFormDataEsListVO appDataAnalysis(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO) throws XbbException {
        Integer subBusinessType = formDataListDTO.getSubBusinessType();
        if (Objects.nonNull(subBusinessType) && Objects.equals(subBusinessType,XbbRefTypeEnum.WAIT_PURCHASE.getCode()) || Objects.equals(subBusinessType,XbbRefTypeEnum.WAIT_PRODUCE.getCode())
                || Objects.equals(subBusinessType,XbbRefTypeEnum.STOCK_SEARCH.getCode())){
            productService.setChildSpecification(formDataListVO.getPaasFormDataESList(),formDataListDTO.getCorpid());
        }
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())) {
            saasListHelp.tempData4Show(formDataListDTO, formDataListVO);
        }
        if (Objects.equals(formDataListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            // 下拉框元素特殊处理
            specialHandleItem(formDataListDTO, formDataListVO);
            // 只存数据库未存es数据处理
            saasListHelp.setOnlyDBData(formDataListDTO, formDataListVO);
        }
        if (Objects.equals(subBusinessType , XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode()) && Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.PRODUCT.getCode())){
            saasListHelp.setOption(formDataListVO, formDataListDTO);
        }
        saasListHelp.analysisSaasDataList(formDataListVO, formDataListDTO.getExplainMap());
        formDataListAnalysisDataHelp.analysisDataList(formDataListDTO, formDataListVO);
        formDataListAnalysisDataHelp.analysisAmountOfThousandBits(formDataListVO, false);
        if (Objects.equals(formDataListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            specialHandle(formDataListDTO, formDataListVO);
        }
        // 摘要和标题的封装
        formDataListVO = ExplainUtil.getValueByData(formDataListVO, formDataListDTO.getFormMap(), formDataListDTO.getFormIdAndHeadListMap());
         // 红冲合同的计划收款金额、未收金额、坏账金额默认值情况下为0 为了保持和saas以前的一样 这里要改成 --
        formDataListAnalysisDataHelp.redPaymentShowHandle(formDataListVO);
        return formDataListVO;
    }
    /**
     * 上部按钮权限和下部按钮权限
     *
     * @param formDataListDTO 前端传参
     * @param formDataListVO  封装回参
     * @return void
     * @throws XbbException 业务异常
     * @author 吴峰
     * @date 2019/3/26 21:09
     */
    public void setButtons(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO) throws XbbException {
        try {
            String corpid = formDataListDTO.getCorpid();
            Integer subBusinessType = formDataListDTO.getSubBusinessType();
            Integer businessType = formDataListDTO.getBusinessType();
            if (Objects.equals(formDataListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                if (Objects.equals(subBusinessType, XbbRefTypeEnum.WARNING_SEARCH.getCode())
                        || Objects.equals(subBusinessType, XbbRefTypeEnum.GUARANTEE_SEARCH.getCode())) {
                    subBusinessType = XbbRefTypeEnum.STOCK_SEARCH.getCode();
                }
                List<ButtonPojo> topButtonList = new ArrayList<>();
                List<ButtonPojo> batchButtonList = new ArrayList<>();
                PaasFormEntityExt form = formDataListVO.getForm();
                //获取顶部和底部按钮(提取)
                getTopAndButtonList(formDataListDTO, corpid, subBusinessType, topButtonList, batchButtonList, form, formDataListVO.getHeadList());
                dealLabelBatch(formDataListDTO, batchButtonList);
                formDataListVO.setTopPermissions(topButtonList);
                formDataListVO.setBottomPermissions(batchButtonList);
            } else if (Objects.equals(formDataListDTO.getSaasMark(), SaasMarkEnum.PAAS.getCode())) {
                UserFormPermissionVO userFormPermissionVO = userService.getUserFormPermissionInternal(corpid,
                        formDataListDTO.getUserId(), formDataListDTO.getAppId(), formDataListDTO.getMenuId());
                setListButtonPermission(formDataListDTO, formDataListVO, userFormPermissionVO, formDataListDTO.getDel());
                if (Objects.equals(formDataListDTO.getDel(), DelEnum.NORMAL.getDel())) {
                    dealLabelBatch(formDataListDTO, formDataListVO.getBottomPermissions());
                }
            }
            cloudCodeHelp.setCloudCodeListButton(corpid, formDataListDTO.getLoginUser().getDynamicPermSet(), formDataListDTO.getAppId(), formDataListDTO.getFormId(),
                    formDataListDTO.getBusinessType(), formDataListVO);
            // 待系列businesstype特殊处理
            if ((Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(),businessType) || Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(),businessType)) && Objects.equals(XbbRefTypeEnum.WAIT_PURCHASE.getCode(),subBusinessType)){
                businessType = XbbRefTypeEnum.WAIT_PURCHASE.getCode();
            }
            CustomButtonListDTO customButtonListDTO = new CustomButtonListDTO();
            customButtonListDTO.setBusinessType(businessType);
            customButtonListDTO.setFormId(formDataListDTO.getFormId());
            customButtonListDTO.setSaasMark(formDataListDTO.getSaasMark());
            customButtonListDTO.setCorpid(formDataListDTO.getCorpid());
            customButtonListDTO.setLoginUser(formDataListDTO.getLoginUser());
            customButtonListDTO.setType(ButtonTypeEnum.LIST.getCode());
            CustomButtonListVO formCustomButtonListVO = customButtonService.listByPermission(customButtonListDTO);
            List<ButtonPojo> list = formDataListVO.getBottomPermissions();
            if (Objects.nonNull(formCustomButtonListVO) && CollectionsUtil.isNotEmpty(formCustomButtonListVO.getCustomButtonList())) {
                formCustomButtonListVO.getCustomButtonList().forEach(item->{
                    ButtonPojo buttonPojo = new ButtonPojo();
                    buttonPojo.setActionList(item.getActionList());
                    buttonPojo.setValue(item.getName());
                    buttonPojo.setAttr(PaasConstant.LOW_CODE);
                    list.add(buttonPojo);
                });
            }
            formDataListVO.setBottomPermissions(list);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormData.setButtons 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 批量打标签按钮和批量移除标签
     *      产品这样设计的
     * @param formDataListDTO
     * @param batchButtonList
     * @throws XbbException
     */
    private void dealLabelBatch(FormDataListDTO formDataListDTO, List<ButtonPojo> batchButtonList) throws XbbException {

        // 回收站不支持编辑
        List<Integer> comparables = Arrays.asList(XbbRefTypeEnum.CUSTOMER_RECYCLE.getCode(), XbbRefTypeEnum.CLUE_RECYCLE.getCode());
        if (comparables.contains(formDataListDTO.getSubBusinessType())){
            return;
        }

        // 特殊两个批量按钮,批量打标签,批量移除标签
        FieldAttrEntity labelField = null;
        Map<String, FieldAttrEntity> explainMap = formDataListDTO.getExplainMap();
        if (Objects.nonNull(explainMap)) {
            // 获取标签fieldAttrEntity
            for(FieldAttrEntity fieldAttrEntity :explainMap.values()){
                if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LABEL.getType())){
                    labelField = fieldAttrEntity;
                    break;
                }
            }
        }
        if (Objects.nonNull(labelField)) {
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            BeanUtil.copyProperties(formDataListDTO, handlerExplainDTO);
            // 高级权限可编辑并且高级权限可见，并且字段是可见的 就展示这两个按钮
            if (Objects.equals(labelField.getVisible(),1) && ExplainUtil.isEditableOfScope(labelField, handlerExplainDTO) && (!ExplainUtil.invisibleOfScope(labelField, handlerExplainDTO))){
                // -----判断是否有该业务或者该表单的编辑权限，开始
                VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO();
                BeanUtil.copyProperties(formDataListDTO, verifyUpdatePermissionDTO);
                UserVO userVO = verifyUpdatePermissionDTO.getLoginUser();
                if (Objects.equals(SaasMarkEnum.SAAS.getCode(), formDataListDTO.getSaasMark())) {
                    Integer businessType = verifyUpdatePermissionDTO.getBusinessType();
                    UpdateProPermissionAliasEnum updateProPermissionAliasEnum = UpdateProPermissionAliasEnum.getByCode(businessType);
                    if (Objects.nonNull(updateProPermissionAliasEnum)) {
                        if (!userVO.getPermSet().contains(updateProPermissionAliasEnum.getAlias())) {
                            return;                        }
                    }
                } else {
                    Set<Long> idSet = ProPermissionHelp.getPaasEditMenuIdSet(userVO.getPaasPermissions());
                    if (!userVO.isAdminOrBoss() && !idSet.contains(verifyUpdatePermissionDTO.getMenuId())) {
                        return;
                    }
                }
                if (Objects.equals(labelField.getIsOpen(), BasicConstant.ZERO)){
                    return;
                }
                // -----判断是否有该业务或者该表单的编辑权限，结束

                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasButtonEnum.ADD_LABEL.getAttr());
                buttonPojo.setValue(SaasButtonEnum.ADD_LABEL.getValue());
                batchButtonList.add(buttonPojo);
                ButtonPojo buttonPojo1 = new ButtonPojo();
                buttonPojo1.setAttr(SaasButtonEnum.REMOVE_LABEL.getAttr());
                buttonPojo1.setValue(SaasButtonEnum.REMOVE_LABEL.getValue());
                batchButtonList.add(buttonPojo1);
            }
        }
    }

    public void setButtons(FormDataListDTO formDataListDTO, PrePaymentBalanceListVO prePaymentBalanceListVO) throws XbbException {
        try {
            String corpid = formDataListDTO.getCorpid();
            Integer subBusinessType = formDataListDTO.getSubBusinessType();
            if (Objects.equals(formDataListDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                List<ButtonPojo> topButtonList = new ArrayList<>();
                List<ButtonPojo> batchButtonList = new ArrayList<>();
                PaasFormEntityExt form = prePaymentBalanceListVO.getForm();
                //获取顶部和底部按钮(提取)
                getTopAndButtonList(formDataListDTO, corpid, subBusinessType, topButtonList, batchButtonList, form, prePaymentBalanceListVO.getHeadList());
                dealLabelBatch(formDataListDTO, batchButtonList);
                prePaymentBalanceListVO.setTopPermissions(topButtonList);
                prePaymentBalanceListVO.setBottomPermissions(batchButtonList);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormData.setButtons 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 获取顶部和底部按钮(提取)
     * @param formDataListDTO
     * @param corpid
     * @param subBusinessType
     * @param topButtonList
     * @param batchButtonList
     * @param form
     * @param explainList 表单解释字段，团队成员需求增加的字段，为了过滤列表批量处理的按钮
     * @throws XbbException
     */
    public void getTopAndButtonList(FormDataListDTO formDataListDTO, String corpid, Integer subBusinessType, List<ButtonPojo> topButtonList, List<ButtonPojo> batchButtonList,
                                    PaasFormEntityExt form, List<FieldAttrEntity> explainList) throws XbbException {
        Integer distributorMark = formDataListDTO.getDistributorMark();
        Integer businessType = formDataListDTO.getBusinessType();
        //替换businesstype 用于获取经销商新增表单的列表页和底部按钮权限
        subBusinessType = XbbRefTypeEnum.transferBusinessType4Distributor(subBusinessType,distributorMark);
        List<ListTopButtonEnum> topButtonEnumList = ListTopButtonEnum.getByBusinessType(subBusinessType);
        List<ListBottomButtonEnum> bottomButtonEnumList = ListBottomButtonEnum.getByBusinessType(subBusinessType);
        Set<String> permSet = formDataListDTO.getLoginUser().getPermSet();
        PaasMenuEntity paasMenuEntity = paasMenuModel.getByKey(form.getMenuId(), form.getCorpid());
        //该公司是否开启客户公海高级模式
        boolean isCustomerSeniorMode = commonHelp.isCustomerPublicPoolSeniorModel(corpid);
        //该公司是否开启线索公海高级模式
        boolean isClueSeniorMode = commonHelp.isCluePublicPoolSeniorModel(corpid);

        if (Objects.isNull(paasMenuEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NOT_EXIST);
        }
        Long modelType = fundSetService.getModelType(corpid, XbbRefTypeEnum.CRM);
        for (ListTopButtonEnum topButtonEnum : topButtonEnumList) {
            String permission = topButtonEnum.getProPermissionAlias();
            // permission为1的按钮一直存在的或还没加权限alias
            if (!permSet.contains(permission) && !Objects.equals(permission, StringConstant.POSITIVE_NUMBER)) {
                continue;
            }
            if (Objects.equals(modelType, ModelTypeEnum.INVOICE.getCode()) || Objects.equals(modelType, ModelTypeEnum.OUTSTOCK.getCode())) {
                if (Objects.equals(ListTopButtonEnum.PAYMENT_ADD, topButtonEnum) || Objects.equals(ListTopButtonEnum.PAYMENT_IMPORT, topButtonEnum)) {
                    continue;
                }
            }
            if (Objects.equals(formDataListDTO.getListGroupId(), Long.valueOf(ListGroupEnum.APPROVAL.getCode()))
                    && (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.IMPORT.getAttr()))) {
                continue;
            }
            //待系列原入口按钮需要做公司版本校验
            if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.WAIT_PURCHASE.getAttr())
                    || Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.WAIT_INSTOCK.getAttr())
                    || Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.WAIT_OUTSTOCK.getAttr())) {
                BasePackageInfoVO basePackageInfoVO = packageHelp.getBasePackageInfoFromRedis(corpid);
                Integer feeType = basePackageInfoVO.getFeeType();
                //只有标准版做限制
                //根据套餐获取当前公司套餐不能看到的菜单
                if (Objects.equals(basePackageInfoVO.getFeeType(), PackageTypeEnum.STANDARD.getType())) {
                    //获取公司创建时间,上线后新公司标准版才限制
                    CompanyEntity company = companyModel.getByKey(corpid);
                    if (company != null) {
                        if (company.getAddTime() > BasicConstant.JXC_ONLINE_DATE) {
                            continue;
                        }
                    }
                }
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(topButtonEnum.getAnEnum(), buttonPojo);
            if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.IMPORT.getAttr())) {
                ButtonExtraPojo buttonExtraPojo = new ButtonExtraPojo();
                buttonExtraPojo.setImportTitle(paasMenuEntity.getName());
                buttonPojo.setButtonExtra(buttonExtraPojo);
            }
            if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.EXPORT.getAttr())) {
                List<ButtonPojo> subButtonList = new ArrayList<ButtonPojo>(){{
                    add(new ButtonPojo(){{BeanUtil.copyProperties(topButtonEnum.getAnEnum(), this);}});
                }};
                List<SaasSubButtonEnum> saasSubButtonEnumList = SaasSubButtonEnum.getByPermissionAlias(XbbRefTypeEnum.transferBusinessType4Distributor(formDataListDTO.getSubBusinessType(),formDataListDTO.getDistributorMark()),topButtonEnum,formDataListDTO.getLoginUser().getPermSet());
                saasSubButtonEnumList.forEach(item->{
                    subButtonList.add(new ButtonPojo(){{setAttr(item.getAlias());setValue(item.getName());}});
                });
                buttonPojo.setSubButtons(subButtonList);
            }
            if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.SET_PRINT.getAttr()) && Objects.equals(subBusinessType, XbbRefTypeEnum.CUSTOMER_STATEMENT_STATISTIC.getCode())) {
                // 对账单打印设置需要传对账流水的formId和appId
                PaasFormEntityExt paasFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode(), corpid, distributorMark, null);
                ButtonExtraPojo buttonExtraPojo = new ButtonExtraPojo();
                buttonExtraPojo.setBusinessType(XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode());
                buttonExtraPojo.setFormId(paasFormEntity.getId());
                buttonExtraPojo.setAppId(formDataListDTO.getAppId());
                buttonPojo.setButtonExtra(buttonExtraPojo);
            }
            if (Objects.equals(topButtonEnum.getAnEnum().getAttr(),SaasButtonEnum.DELIVERY_ANALYSIS.getAttr())){
                ChartCategoryEntity chartCategoryEntity = chartCategoryModel.getEntityByAlias(new HashMap<String,Object>(){{put("alias",SaasButtonEnum.DELIVERY_ANALYSIS.getAttr());put("corpid",formDataListDTO.getCorpid());}});
                if (Objects.nonNull(chartCategoryEntity)){
                    buttonPojo.setCategoryId(chartCategoryEntity.getId());
                    buttonPojo.setParentId(chartCategoryEntity.getParentId());
                }
            }
            buttonPojo.setDistributorMark(distributorMark);
            topButtonList.add(buttonPojo);
        }
        for (ListBottomButtonEnum bottomButtonEnum : bottomButtonEnumList) {
            String permission = bottomButtonEnum.getProPermissionAlias();
            // permission为1的按钮一直存在的或还没加权限alias
            if (!permSet.contains(permission) && !Objects.equals(permission, StringConstant.POSITIVE_NUMBER)) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(bottomButtonEnum.getAnEnum(), buttonPojo);
            if (Objects.equals(bottomButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.IMPORT.getAttr())) {
                ButtonExtraPojo buttonExtraPojo = new ButtonExtraPojo();
                buttonExtraPojo.setImportTitle(paasMenuEntity.getName());
                buttonPojo.setButtonExtra(buttonExtraPojo);
            }
            buttonPojo.setDistributorMark(distributorMark);
            //塞入底部
            batchButtonList.add(buttonPojo);
        }
        List<ListBatchEnum> listBatchEnumList = ListBatchEnum.getByBusinessType(subBusinessType);
        //将subbusinessType再替换回来
        subBusinessType = XbbRefTypeEnum.transferBusinessType2Index(subBusinessType);
        boolean distributorMarkFlag = Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode());

        // 目前整理的审批中列表支持的批量操作只有打印，具体信息见语雀文档：https://xbb.yuque.com/kgwhab/lrgi3l/zd25ra
        if (Objects.equals(formDataListDTO.getDefaultGroup(), 1) && Objects.equals(formDataListDTO.getListGroupId(), Long.valueOf(ListGroupEnum.APPROVAL.getCode()))) {
            listBatchEnumList.removeIf(item -> !Objects.equals(item.getAnEnum(), SaasBatchEnum.BATCH_PRINT));
        }
        TeamListBatchPermissionVO teamListBatchPermissionVO = teamDataHelp.getTeamListBatchPermission(formDataListDTO, explainList);
        Map<String, Boolean> teamMap = teamListBatchPermissionVO.getTeamMap();
        if (Objects.isNull(teamMap)) {
            teamMap = new HashMap<>();
        }
        List<String> listTeamBatchButtonAttr = SaasBatchEnum.getListTeamBatchButton();
        for (ListBatchEnum batchEnum : listBatchEnumList) {
            if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), distributorMark) && listTeamBatchButtonAttr.contains(batchEnum.getAnEnum().getAttr())) {
                Boolean teamBatchPer = teamMap.get(batchEnum.getAnEnum().getAttr());
                if (Objects.nonNull(teamBatchPer) && !teamBatchPer) {
                    continue;
                }
            }
            if (Objects.equals(subBusinessType,XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode()) && Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.PURCHASE.getCode())){
                continue;
            }
            if (Objects.equals(subBusinessType,XbbRefTypeEnum.WAIT_OUTSTOCK.getCode()) && Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.CONTRACT.getCode())){
                continue;
            }
            if (ModelTypeEnum.INVOICE.getCode().equals(modelType) &&
                    Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.MERGE_INVOICE.getAttr()) &&
                    (Objects.equals(subBusinessType, XbbRefTypeEnum.PAYMENT.getCode()) || Objects.equals(subBusinessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()))
            ) {
                continue;
            }
            //经销商模式，销项发票、回款单无批量删除
            boolean noDel = distributorMarkFlag && (Objects.equals(batchEnum, ListBatchEnum.INVOICE_DEL) || Objects.equals(batchEnum, ListBatchEnum.PAYMENT_SHEET_DEL));
            if (noDel) {
                continue;
            }
            //只有公司开了客户或者线索公海高级模式,才会返回变更分组权限
            if (Objects.equals(businessType,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())){
                if (Objects.equals(batchEnum.getAnEnum().getAttr(),SaasBatchEnum.SWITCH_PUBLIC_GROUP.getAttr()) && !isCustomerSeniorMode){
                    continue;
                }
            }
            if (Objects.equals(businessType,XbbRefTypeEnum.CLUE.getCode())){
                if (Objects.equals(batchEnum.getAnEnum().getAttr(),SaasBatchEnum.SWITCH_PUBLIC_GROUP.getAttr()) && !isClueSeniorMode){
                    continue;
                }
            }
            // permission为1的按钮一直存在的
            String permissionAlias = batchEnum.getProPermissionAlias();
            if (!permSet.contains(permissionAlias) && !Objects.equals(permissionAlias, StringConstant.POSITIVE_NUMBER) && !Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.CONTRACT_COMPARE.getAttr())) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(batchEnum.getAnEnum(), buttonPojo);
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.MERGE_INVOICE.getAttr())) {
                buttonPojo.addBusinessType(XbbRefTypeEnum.INVOICE.getCode());
            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.ADD_VISIT_PLAN.getAttr())) {
                buttonPojo.addBusinessType(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.COMMUNICATE_NOTIFY.getAttr())) {
                buttonPojo.addBusinessType(XbbRefTypeEnum.PUSH_NOTIFY.getCode());
            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.PURCHASE.getAttr())) {
                buttonPojo.addBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.MERGE_PAYMENT.getAttr()) ){
                buttonPojo.addBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.MEEGE_PURCHASE_INVOICE.getAttr()) ){
                buttonPojo.addBusinessType(XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.SET_PAID.getAttr())) {
                if (commonHelp.isOpenWorkFlow(corpid)) {
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("del", 0);
                    params.put("businessType", XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                    params.put("corpid", corpid);
                    params.put("distributorMark", distributorMark);
                    //查询回款单的paasForm信息
                    List<PaasFormEntityExt> paasFormEntityExts = paasFormModel.findEntitys(params);
                    Long paymentSheetFormId = CollectionsUtil.isNotEmpty(paasFormEntityExts) ? paasFormEntityExts.get(BasicConstant.ZERO).getId() : 0L;
                    List<WorkflowEntity> list = workflowFormDataOperationService.getSatisfyTriggerEntitys(corpid,
                            paymentSheetFormId, XbbRefTypeEnum.PAYMENT_SHEET.getCode(), Arrays.asList(TriggerEventTypeEnum.ONLY_ADD.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
                    //如果有工作流审批并且至少已有一个启用了工作流
                    if (CollectionsUtil.isNotEmpty(list) && list.stream().map(WorkflowEntity::getEnable).collect(Collectors.toList()).contains(BasicConstant.ONE)) {
                        buttonPojo.setDisabled(1);
                        buttonPojo.setNeedRemind(1);
                        buttonPojo.setRemindMsg(I18nMessageUtil.getMessage(ErrorMessageConstant.PAYMENT_SHEET_APPROVEL_NOT_ADD));
                    }
                } else {
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("del", 0);
                    params.put("businessType", XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                    params.put("corpid", corpid);
                    params.put("distributorMark", distributorMark);
                    //查询回款单的paasForm信息
                    List<PaasFormEntityExt> paasFormEntityExts = paasFormModel.findEntitys(params);
                    if (CollectionsUtil.isNotEmpty(paasFormEntityExts)) {
                        params.put("formId", paasFormEntityExts.get(BasicConstant.ZERO).getId());
                    }
                    params.put("enable",1);
                    params.put(ParameterConstant.COLUMNS, "enable");
                    List<PaasProcessTemplateEntityExt>  processList = paasProcessTemplateModel.list(params);
                    if (!processList.isEmpty() && Objects.equals(processList.get(0).getEnable(), 1)) {
                        buttonPojo.setDisabled(1);
                        buttonPojo.setNeedRemind(1);
                        buttonPojo.setRemindMsg(I18nMessageUtil.getMessage(ErrorMessageConstant.PAYMENT_SHEET_APPROVEL_NOT_ADD));
                    }
                }

            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.MERGE_PAY_PAID.getAttr()) ){
                buttonPojo.addBusinessType(XbbRefTypeEnum.PAY_SHEET.getCode());
            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.SET_PAY_PAID.getAttr())) {
                if (commonHelp.isOpenWorkFlow(corpid)) {
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("del", 0);
                    params.put("businessType", XbbRefTypeEnum.PAY_SHEET.getCode());
                    params.put("corpid", corpid);
                    List<PaasFormEntity> paasFormEntities = paasFormModel.findEntity(params);
                    Long paySheetFormId = CollectionsUtil.isNotEmpty(paasFormEntities) ? paasFormEntities.get(BasicConstant.ZERO).getId() : 0L;
                    List<WorkflowEntity> list = workflowFormDataOperationService.getSatisfyTriggerEntitys(corpid,
                            paySheetFormId, XbbRefTypeEnum.PAY_SHEET.getCode(), Arrays.asList(TriggerEventTypeEnum.ONLY_ADD.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
                    //如果有工作流审批并且至少已有一个启用了工作流
                    if (CollectionsUtil.isNotEmpty(list) && list.stream().map(WorkflowEntity::getEnable).collect(Collectors.toList()).contains(BasicConstant.ONE)) {
                        buttonPojo.setDisabled(1);
                        buttonPojo.setNeedRemind(1);
                        buttonPojo.setRemindMsg(I18nMessageUtil.getMessage(ErrorMessageConstant.PAY_SHEET_APPROVEL_NOT_ADD));
                    }
                } else {
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("del", 0);
                    params.put("businessType", XbbRefTypeEnum.PAY_SHEET.getCode());
                    params.put("corpid", corpid);
                    params.put("enable",1);
                    params.put(ParameterConstant.COLUMNS, "enable");
                    List<PaasProcessTemplateEntityExt>  processList = paasProcessTemplateModel.list(params);
                    if (!processList.isEmpty() && Objects.equals(processList.get(0).getEnable(), 1)) {
                        buttonPojo.setDisabled(1);
                        buttonPojo.setNeedRemind(1);
                        buttonPojo.setRemindMsg(I18nMessageUtil.getMessage(ErrorMessageConstant.PAY_SHEET_APPROVEL_NOT_ADD));
                    }
                }

            }
            if (Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.SEND_SMS.getAttr())) {
                PaasAppEntity entity = paasAppModel.getByAlias(XbbRefTypeEnum.GROUP_MESSAGE.getAlias(), corpid);
                if (entity == null || Objects.equals(entity.getEnable(), BasicConstant.ZERO)) {
                    continue;
                }
            }
            Long listGroupIdLong = formDataListDTO.getListGroupId();
            if (listGroupIdLong != null) {
                Integer listGroupId = listGroupIdLong.intValue();
                boolean ifMergeInvoicePayment = Objects.equals(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), subBusinessType) &&
                        Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.MERGE_INVOICE.getAttr()) &&
                        (Objects.equals(ListGroupEnum.PAYMENT_SHEET_RED.getCode(), listGroupId) || Objects.equals(ListGroupEnum.PAYMENT_SHEET_BAD.getCode(), listGroupId));
                boolean ifMergeInvoicePay = Objects.equals(XbbRefTypeEnum.PAY_SHEET.getCode(), subBusinessType) &&
                        Objects.equals(batchEnum.getAnEnum().getAttr(), SaasBatchEnum.MEEGE_PURCHASE_INVOICE.getAttr()) &&
                        (Objects.equals(ListGroupEnum.PAY_SHEET_RED.getCode(), listGroupId) || Objects.equals(ListGroupEnum.PAY_SHEET_BAD.getCode(), listGroupId));
                if (ifMergeInvoicePayment || ifMergeInvoicePay) {
                    continue;
                }
            }
            buttonPojo.setDistributorMark(distributorMark);
            if (Objects.equals(batchEnum.getAnEnum().getAttr(),SaasBatchEnum.CONTRACT_COMPARE.getAttr())){
                Boolean showCompareButton = contractCompareUtil.showCompareButton(corpid, permSet, formDataListDTO.getUserId());
                if (!showCompareButton){
                    continue;
                }
            }
            batchButtonList.add(buttonPojo);
        }
    }

    /**
     * 根据用户具有的该表单的权限显隐列表上部和下部的操作按钮
     *
     * @param formDataListVO       列表接口返回的VO，
     *                             本处会设置该VO对应的 topPermissions 和 bottomPermissions 属性
     * @param userFormPermissionVO 用户具有的该表单的权限
     * @param del                  为0普通列表，为1数据回收站
     */
    public void setListButtonPermission(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO, UserFormPermissionVO userFormPermissionVO, int del) {
        //TODO haibin.zhang paas列表按钮
        PermissionTermsPojo permissionTerms = userFormPermissionVO.getFormPermission().getPermission();
        // 上部按钮权限
        List<ButtonPojo> topPermissions = new ArrayList<>();
        // 下部按钮权限
        List<ButtonPojo> bottomPermissions = new ArrayList<>();
        List<FieldAttrEntity> fieldAttrList = formDataListVO.getHeadList();
        // 添加一行操作列
        FieldAttrEntity fieldOption = new FieldAttrEntity();
        fieldOption.setAttr(ListOptionEnum.OPTION.getAttr());
        fieldOption.setAttrName(ListOptionEnum.OPTION.getAttrName());
        fieldOption.setFieldType(FieldTypeEnum.OPTION.getType());
        fieldAttrList.add(0, fieldOption);
        Boolean editBoolean = false;
        Boolean deleteBoolean = false;
        List<PaasFormDataEntityExt> paasFormDataList = formDataListVO.getPaasFormDataESList();
        Boolean isAdmin = userFormPermissionVO.getIsAdminOrBoss();
        // 注意顺序
        if (del == 0) {
            if (permissionTerms.getCreate().equals(1) || isAdmin) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasButtonEnum.ADD.getAttr());
                buttonPojo.setValue(SaasButtonEnum.ADD.getValue());
                buttonPojo.setType(SaasButtonEnum.ADD.getType());
                topPermissions.add(buttonPojo);
            }
            if (permissionTerms.getImports().equals(1) || isAdmin) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasButtonEnum.IMPORT.getAttr());
                buttonPojo.setValue(SaasButtonEnum.IMPORT.getValue());
                topPermissions.add(buttonPojo);
            }
            if (permissionTerms.getExport().equals(1) || isAdmin) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasButtonEnum.EXPORT.getAttr());
                buttonPojo.setValue(SaasButtonEnum.EXPORT.getValue());
                buttonPojo.setSubButtons(new ArrayList<ButtonPojo>(){{
                    add(new ButtonPojo(){{setAttr(SaasButtonEnum.EXPORT.getAttr());setValue(SaasButtonEnum.EXPORT.getValue());}});
                    add(new ButtonPojo(){{setAttr(SaasButtonEnum.CUSTOM_EXPORT.getAttr());setValue(SaasButtonEnum.CUSTOM_EXPORT.getValue());}});
                }});
                topPermissions.add(buttonPojo);
            }
            if (userFormPermissionVO.getIsAdminOrBoss()) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasButtonEnum.DATA_TRASH.getAttr());
                buttonPojo.setValue(SaasButtonEnum.DATA_TRASH.getValue());
                // 回收站列表的参数
                ButtonExtraPojo buttonExtra = new ButtonExtraPojo();
                PaasFormEntityExt paasFormEntityExt = formDataListVO.getForm();
                buttonExtra.setAppId(paasFormEntityExt.getAppId());
                buttonExtra.setFormId(paasFormEntityExt.getId());
                buttonExtra.setMenuId(paasFormEntityExt.getMenuId());
                buttonExtra.setSaasMark(paasFormEntityExt.getSaasMark());
                buttonExtra.setDel(DelEnum.DELETE.getDel());
                buttonPojo.setButtonExtra(buttonExtra);
                topPermissions.add(buttonPojo);
            }
            // 是否审批中分组
            boolean isDefaultApprovalGroup = Objects.equals(formDataListDTO.getDefaultGroup(), 1) && Objects.equals(formDataListDTO.getListGroupId(), Long.valueOf(ListGroupEnum.APPROVAL.getCode()));
            if (!isDefaultApprovalGroup && (permissionTerms.getUpdate().equals(1) || isAdmin)) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasBatchEnum.BATCH_EDIT.getAttr());
                buttonPojo.setValue(SaasBatchEnum.BATCH_EDIT.getValue());
                bottomPermissions.add(buttonPojo);
            }
            if (permissionTerms.getPrint().equals(1) || isAdmin) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasBatchEnum.BATCH_PRINT.getAttr());
                buttonPojo.setValue(SaasBatchEnum.BATCH_PRINT.getValue());
                buttonPojo.setType(SaasBatchEnum.BATCH_PRINT.getType());
                bottomPermissions.add(buttonPojo);
            }
            if (!isDefaultApprovalGroup && (permissionTerms.getDelete().equals(1) || isAdmin)) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasBatchEnum.DEL.getAttr());
                buttonPojo.setValue(SaasBatchEnum.DEL.getValue());
                bottomPermissions.add(buttonPojo);
            }
            List<FieldAttrEntity> headList = formDataListVO.getHeadList();
            for (FieldAttrEntity entity : headList) {
                if (!isDefaultApprovalGroup && Objects.equals(entity.getAttr(), FieldTypeEnum.OWNERID.getAlias()) && (permissionTerms.getHandleOver().equals(1) || isAdmin)) {
                    // paas表单，如果有负责人字段，就出现移交；如果没有，则不显示移交操作
                    ButtonPojo handover = new ButtonPojo();
                    handover.setAttr(SaasBatchEnum.HANDOVER.getAttr());
                    handover.setValue(SaasBatchEnum.HANDOVER.getValue());
                    bottomPermissions.add(handover);
                }
                //paas表单，如果当前表单模板中协同人字段存在且开启，那么就有批量添加协同人权限、批量删除协同人权限
                if (Objects.equals(entity.getAttr(), FieldTypeEnum.COUSERID.getAlias())
                        && Objects.equals(entity.getIsOpen(), BasicConstant.ONE)) {
                    ButtonPojo batchAddCo = new ButtonPojo();
                    batchAddCo.setAttr(SaasBatchEnum.ADD_TEAM_PERSON.getAttr());
                    batchAddCo.setValue(SaasBatchEnum.ADD_TEAM_PERSON.getValue());
                    bottomPermissions.add(batchAddCo);
                    ButtonPojo batchDelCo = new ButtonPojo();
                    batchDelCo.setAttr(SaasBatchEnum.DEL_TEAM_PERSON.getAttr());
                    batchDelCo.setValue(SaasBatchEnum.DEL_TEAM_PERSON.getValue());
                    bottomPermissions.add(batchDelCo);
                }
            }
            for (PaasFormDataEntityExt item : paasFormDataList) {
                JSONObject data = item.getData();
                List<ButtonPojo> optionList = new ArrayList<>();
                optionList.add(new ButtonPojo(ListOptionTabEnum.VIEW));
                JSONObject option = new JSONObject();
                option.put("value", optionList);
                data.put(ListOptionEnum.OPTION.getAttr(), option);
            }
        } else if (del == 1) {
            if (userFormPermissionVO.getIsAdminOrBoss()) {
                // 恢复
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr(SaasBatchEnum.REVERT_BATCH.getAttr());
                buttonPojo.setValue(SaasBatchEnum.REVERT_BATCH.getValue());
                bottomPermissions.add(buttonPojo);
                // 彻底删除
                ButtonPojo deleteComplete = new ButtonPojo();
                deleteComplete.setAttr(SaasBatchEnum.REMOVE_COMPLETELY.getAttr());
                deleteComplete.setValue(SaasBatchEnum.REMOVE_COMPLETELY.getValue());
                bottomPermissions.add(deleteComplete);
                for (PaasFormDataEntityExt item : paasFormDataList) {
                    JSONObject data = item.getData();
                    List<ButtonPojo> optionList = new ArrayList<>();
                    optionList.add(new ButtonPojo(ListOptionTabEnum.VIEW));
                    optionList.add(new ButtonPojo(ListOptionTabEnum.REVERT));
                    optionList.add(new ButtonPojo(ListOptionTabEnum.COMPLETE_DEL));
                    JSONObject option = new JSONObject();
                    option.put("value", optionList);
                    data.put(ListOptionEnum.OPTION.getAttr(), option);
                }
            }
        }
        formDataListVO.setTopPermissions(topPermissions);
        formDataListVO.setBottomPermissions(bottomPermissions);
    }

    /**
     * 列表排序,字段隐藏
     *
     * @param formDataListDTO 前端传参
     * @author haibin.zahng
     */
    public void setListColumn(FormDataListDTO formDataListDTO) {
        Map<String, String> sortMap = formDataListDTO.getSortMap();
        if (sortMap == null || sortMap.isEmpty()) {
            setSortMap(formDataListDTO);
        }
    }


    private String getKey(Integer subBusinessType,Long appId,Long formId) {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(subBusinessType);
        switch (xbbRefTypeEnum){
            case STOCK_SEARCH:
            case WARNING_SEARCH:
            case GUARANTEE_SEARCH:
            case WAIT_PURCHASE:
            case WAIT_PRODUCE:
            case WAIT_OUTSTOCK:
                return "";
            default:
                return appId + "_" + formId;
        }
    }
    /**
     * 设置字段排序
     * @param formDataListDTO
     */
    private void setSortMap(FormDataListDTO formDataListDTO){
        Map<String, String> sortMap = businessListHelp.getSortMap(formDataListDTO.getSubBusinessType(), formDataListDTO.getBusinessType(), formDataListDTO.getFormId(), formDataListDTO.getAppId(), formDataListDTO.getCorpid(), formDataListDTO.getListGroupId(), formDataListDTO.getUserId(), formDataListDTO.getSortMap());
        formDataListDTO.setSortMap(sortMap);
    }

    /**
     * 获取表单
     * @param formDataListDTO
     * @return
     * @throws XbbException
     */
    public PaasFormEntityExt getForm(FormDataListDTO formDataListDTO) throws XbbException{
        Long formId = formDataListDTO.getFormId();
        String corpid = formDataListDTO.getCorpid();
        Integer businessType = formDataListDTO.getBusinessType();
        PaasFormEntityExt form = new PaasFormEntityExt();
        if (formId == null) {
            SheetTypeEnum sheetTypeEnum = SheetTypeEnum.getByBusinessType(businessType);
            boolean sheetFlag = SheetTypeEnum.validateSheet(sheetTypeEnum);
            if (sheetFlag) {
                form = paasFormModel.getByBusinessType4Distributor(sheetTypeEnum.getXbbRefTypeEnum().getCode(), corpid, formDataListDTO.getDistributorMark(), null);
            } else {
                form = paasFormModel.getByBusinessType4Distributor(businessType, corpid, formDataListDTO.getDistributorMark(), null);
            }
        } else {
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderFormEntityExt workOrderForm = workOrderFormModel.getByKey(formId,corpid);
                if (workOrderForm == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderForm, form);
            } else {
                form = paasFormModel.getByKey(formId, corpid);
            }
        }
        if (form == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        formDataListDTO.setDistributorMark(form.getDistributorMark());
        return form;
    }

    /**
     * 列表解释处理
     * @param formDataListDTO
     * @param form
     * @return
     * @throws XbbException
     */
    public HandleExplainPojo handlExplains(FormDataListDTO formDataListDTO, PaasFormEntityExt form) throws XbbException{
        String corpid = formDataListDTO.getCorpid();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(form.getId(), corpid);
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Integer distributorMark = paasFormExplainEntity.getDistributorMark();
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);

        // 【审批中】分组数据禁用快速编辑
        if (Objects.equals(formDataListDTO.getDefaultGroup(), 1) && Objects.equals(formDataListDTO.getListGroupId(), Long.valueOf(ListGroupEnum.APPROVAL.getCode()))) {
            explainList.forEach(item -> item.setEditable(0));
        }

        List<String> fieldList = new ArrayList<>();
        Integer saasMark = formDataListDTO.getSaasMark();
        explainList.forEach(item->{
            if (!Objects.equals(FieldTypeEnum.SUB_FORM.getType(), item.getFieldType())) {
                fieldList.add(item.getAttr());
            }
            // saas解释处理
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
                if (Objects.equals(item.getFieldType(), FieldTypeEnum.LINK_BUSINESS_SINGLE.getType())
                        || Objects.equals(item.getFieldType(), FieldTypeEnum.LINK_BUSINESS_MULTI.getType())) {
                    LinkDetailPojo linkDetail = new LinkDetailPojo();
                    linkDetail.setBusinessType(item.getLinkedType());
                    linkDetail.setSubBuisenssType(item.getLinkedType());
                    linkDetail.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    item.setLinkDetail(linkDetail);
                }
            }
        });
        saasListHelp.handelSaasSpecialList(explainList, formDataListDTO.getBusinessType(),formDataListDTO.getSubBusinessType());
        if (Objects.equals(formDataListDTO.getSubBusinessType(),XbbRefTypeEnum.SMART_REPLENISHMENT.getCode())){
            handleSmartReplenishmentExplain(explainList);
        }
        if (Objects.equals(formDataListDTO.getPlatform(),PlatFormEnum.DINGTALK.getValue())
                && Objects.equals(formDataListDTO.getSubBusinessType(),XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode())
                && Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.PRODUCT.getCode())){
            saasListHelp.handleWaitInstockExplain(explainList);
        }
        if (Objects.equals(formDataListDTO.getPlatform(),PlatFormEnum.DINGTALK.getValue())
                && Objects.equals(formDataListDTO.getSubBusinessType(),XbbRefTypeEnum.WAIT_OUTSTOCK.getCode())
                && Objects.equals(formDataListDTO.getBusinessType(),XbbRefTypeEnum.PRODUCT.getCode())){
            saasListHelp.handleWaitOutstockExplain(explainList);
        }
        Map<String,FieldAttrEntity> explainMap = paasFormExplainService.getExpalinMap(explainList, paasFormExplainEntity.getBusinessType(), corpid,form.getId());
        Integer businessType = formDataListDTO.getBusinessType();
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())) {
            FilterAttrOnOffJXCDTO filterAttrOnOffJXCDTO = new FilterAttrOnOffJXCDTO();
            BeanUtil.copyProperties(formDataListDTO, filterAttrOnOffJXCDTO);
            filterAttrOnOffJXCDTO.setFieldAttrEntityList(explainList);
            filterAttrOnOffJXCDTO.setOperatePageCode(OperatePageEnum.LIST.getCode());
            productModel.filterAttrOnOffJXC(filterAttrOnOffJXCDTO);
            explainList.remove(explainMap.get(ProductEnum.IS_NOTIFY.getAttr()));
            explainMap.remove(ProductEnum.IS_NOTIFY.getAttr());
            explainList.remove(explainMap.get(ProductEnum.STOCK_NOTIFY.getAttr()));
            explainMap.remove(ProductEnum.STOCK_NOTIFY.getAttr());
        }
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode()) && (Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.STOCK_SEARCH.getCode())
                || Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WARNING_SEARCH.getCode()) || Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.GUARANTEE_SEARCH.getCode()))) {
            if (Objects.equals(formDataListDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                explainList.remove(explainMap.get(ProductEnum.VISBLE_DEPT.getAttr()));
                explainMap.remove(ProductEnum.VISBLE_DEPT.getAttr());
                explainList.remove(explainMap.get(ProductEnum.VISBLE_USER.getAttr()));
                explainMap.remove(ProductEnum.VISBLE_USER.getAttr());
//                explainMap.get(ProductEnum.STOCK.getAttr()).setDisableListSort(1);
            }
        }
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode()) && Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.STOCK_SEARCH.getCode())) {
            explainList.remove(explainMap.get(ProductEnum.WAREHOUSE.getAttr()));
            explainMap.remove(ProductEnum.WAREHOUSE.getAttr());
            explainMap.get(ProductEnum.STOCK.getAttr()).setSummaryFlag(SummaryTypeEnum.SUM.getType());
            FieldAttrEntity costAttr = explainMap.get(ProductEnum.COST.getAttr());
            costAttr.setSummaryFlag(SummaryTypeEnum.SUM.getType());
            FieldAttrEntity totalCostAttr = (FieldAttrEntity) CloneUtil.deepClone(costAttr);
            totalCostAttr.setAttr("totalCost");
            totalCostAttr.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.TOTAL_COST));
            totalCostAttr.setDisableListSort(1);
            //新增可用库存量
            FieldAttrEntity stockAttr = explainMap.get(ProductEnum.STOCK.getAttr());
            FieldAttrEntity availableStockAttr = (FieldAttrEntity) CloneUtil.deepClone(stockAttr);
            availableStockAttr.setAttr("availableStock");
            availableStockAttr.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.AVAILABLE_STOCK));
            availableStockAttr.setDisableListSort(1);
            explainList.add(totalCostAttr);
            explainList.add((explainList.indexOf(explainMap.get(ProductEnum.STOCK.getAttr()))+1),availableStockAttr);
            explainMap.put(totalCostAttr.getAttr(), totalCostAttr);
            explainMap.put(availableStockAttr.getAttr(), availableStockAttr);
        } else if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode()) && Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WARNING_SEARCH.getCode())) {
            // web端仓库不需要穿透，但是移动端摘要渲染不能用text
            if (Objects.equals(formDataListDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                explainMap.get(ProductEnum.WAREHOUSE.getAttr()).setFieldType(FieldTypeEnum.TEXT.getType());
                explainMap.get(ProductEnum.WAREHOUSE.getAttr()).setLinkDetail(null);
            }
            explainMap.get(ProductEnum.WAREHOUSE.getAttr()).setDisableListSort(1);
            explainMap.get(ProductEnum.PRODUCT_NO.getAttr()).setDisableListSort(1);
            explainMap.get(ProductEnum.NAME.getAttr()).setDisableListSort(1);
            explainMap.get(ProductEnum.BARCODE.getAttr()).setDisableListSort(1);
            explainMap.get(ProductEnum.UNIT.getAttr()).setDisableListSort(1);
            FieldAttrEntity stockAttr = explainMap.get(ProductEnum.STOCK.getAttr());
            FieldAttrEntity currentNumAttr = (FieldAttrEntity) CloneUtil.deepClone(stockAttr);
            currentNumAttr.setAttr("currentStock");
            currentNumAttr.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.CURRENT_STOCK));
            currentNumAttr.setDisableListSort(1);
            explainList.add(currentNumAttr);
            explainMap.put(currentNumAttr.getAttr(), currentNumAttr);
            FieldAttrEntity minimumNumAttr = (FieldAttrEntity) CloneUtil.deepClone(stockAttr);
            minimumNumAttr.setAttr("minimumStock");
            minimumNumAttr.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.MINIMUM_STOCK));
            minimumNumAttr.setDisableListSort(1);
            explainList.add(minimumNumAttr);
            explainMap.put(minimumNumAttr.getAttr(), minimumNumAttr);
            FieldAttrEntity maximumNumAttr = (FieldAttrEntity) CloneUtil.deepClone(stockAttr);
            maximumNumAttr.setAttr("maximumStock");
            maximumNumAttr.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.MAXIMUM_STOCK));
            maximumNumAttr.setDisableListSort(1);
            explainList.add(maximumNumAttr);
            explainMap.put(maximumNumAttr.getAttr(), maximumNumAttr);
            if (Objects.equals(formDataListDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                explainList.remove(explainMap.get(ProductEnum.STOCK.getAttr()));
                explainMap.remove(ProductEnum.STOCK.getAttr());
            }
        } else if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode()) && Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.GUARANTEE_SEARCH.getCode())) {
            // 产品字段都不支持列表排序
            FieldAttrEntity costFieldAttr = null;
            FieldAttrEntity stockFieldAttr = null;
            for (FieldAttrEntity fieldAttrEntity : explainList) {
                fieldAttrEntity.setDisableListSort(1);
                if (Objects.equals(ProductEnum.COST.getAttr(), fieldAttrEntity.getAttr())) {
                    costFieldAttr = fieldAttrEntity;
                } else if (Objects.equals(ProductEnum.STOCK.getAttr(), fieldAttrEntity.getAttr())) {
                    stockFieldAttr = fieldAttrEntity;
                }
            }
            // 去除产品的仓库和保质期字段
            explainMap.remove(ProductEnum.WAREHOUSE.getAttr());
            explainMap.remove(ProductEnum.SHELF_LIFE_DAYS.getAttr());
            List<FieldAttrEntity> list = new ArrayList<>();
            // 批次号
            FieldAttrEntity batchField = new FieldAttrEntity();
            batchField.setAttr(SelectProductEnum.BATCH.getSaasAttr());
            batchField.setAttrName(SelectProductEnum.BATCH.getAttrName());
            batchField.setFieldType(FieldTypeEnum.TEXT.getType());
            batchField.setVisible(1);
            list.add(batchField);
            // 生产日期
            FieldAttrEntity productDateField = new FieldAttrEntity();
            productDateField.setAttr(SelectProductEnum.PRODUCE_DATE.getSaasAttr());
            productDateField.setAttrName(SelectProductEnum.PRODUCE_DATE.getAttrName());
            productDateField.setFieldType(FieldTypeEnum.DATETIME.getType());
            productDateField.setDateType(DateTypeEnum.YMD.getAlias());
            productDateField.setVisible(1);
            list.add(productDateField);
            // 保质期
            FieldAttrEntity guaranteePeriodField = new FieldAttrEntity();
            guaranteePeriodField.setAttr(SelectProductEnum.GUARANTEE_PERIOD.getSaasAttr());
            guaranteePeriodField.setAttrName(SelectProductEnum.GUARANTEE_PERIOD.getAttrName());
            guaranteePeriodField.setFieldType(FieldTypeEnum.TEXT.getType());
            guaranteePeriodField.setDisableListSort(1);
            guaranteePeriodField.setVisible(1);
            list.add(guaranteePeriodField);
            // 到期日期
            FieldAttrEntity expireDateField = new FieldAttrEntity();
            expireDateField.setAttr(SelectProductEnum.EXPIRE_DATE.getSaasAttr());
            expireDateField.setAttrName(SelectProductEnum.EXPIRE_DATE.getAttrName());
            expireDateField.setFieldType(FieldTypeEnum.DATETIME.getType());
            expireDateField.setDateType(DateTypeEnum.YMD.getAlias());
            expireDateField.setVisible(1);
            list.add(expireDateField);
            // 仓库
            FieldAttrEntity warehouseField = new FieldAttrEntity();
            warehouseField.setAttr(SelectProductEnum.WAREHOUSE.getSaasAttr());
            warehouseField.setAttrName(SelectProductEnum.WAREHOUSE.getAttrName());
            warehouseField.setFieldType(FieldTypeEnum.TEXT.getType());
            warehouseField.setDisableListSort(1);
            warehouseField.setVisible(1);
            list.add(warehouseField);
            // 库存数量
            FieldAttrEntity stockField = new FieldAttrEntity();
            stockField.setAttr(SelectProductEnum.STOCK.getSaasAttr());
            stockField.setAttrName(SelectProductEnum.STOCK.getAttrName());
            stockField.setFieldType(SelectProductEnum.STOCK.getFieldType());
            stockField.setSaasAttr(SelectProductEnum.STOCK.getSaasAttr());
            stockField.setVisible(1);
            if (Objects.nonNull(stockFieldAttr)) {
                stockField.setSummaryFlag(stockFieldAttr.getSummaryFlag());
                stockField.setVisible(stockFieldAttr.getVisible());
                stockField.setVisibleScopeRule(stockFieldAttr.getVisibleScopeRule());
                stockField.setVisibleScopeEnable(stockFieldAttr.getVisibleScopeEnable());
                stockField.setAccuracy(stockFieldAttr.getAccuracy());
            } else {
                stockField.setVisible(1);
            }
            list.add(stockField);
            // 成本
            FieldAttrEntity costField = new FieldAttrEntity();
            costField.setAttr(SelectProductEnum.COST.getSaasAttr());
            costField.setAttrName(SelectProductEnum.COST.getAttrName());
            costField.setFieldType(FieldTypeEnum.TEXT.getType());
            costField.setDisableListSort(1);
            if (Objects.nonNull(costFieldAttr)) {
                costField.setVisible(costFieldAttr.getVisible());
                costField.setVisibleScopeRule(costFieldAttr.getVisibleScopeRule());
                costField.setVisibleScopeEnable(costFieldAttr.getVisibleScopeEnable());
                costField.setSummaryFlag(costFieldAttr.getSummaryFlag());
            } else {
                costField.setVisible(1);
            }
            list.add(costField);
            // 成本小计
            FieldAttrEntity totalCostField = new FieldAttrEntity();
            totalCostField.setAttr(SelectProductEnum.TOTAL_COST.getSaasAttr());
            totalCostField.setAttrName(SelectProductEnum.TOTAL_COST.getAttrName());
            totalCostField.setFieldType(FieldTypeEnum.TEXT.getType());
            if (Objects.nonNull(costFieldAttr)) {
                totalCostField.setVisible(costFieldAttr.getVisible());
                totalCostField.setVisibleScopeRule(costFieldAttr.getVisibleScopeRule());
                totalCostField.setVisibleScopeEnable(costFieldAttr.getVisibleScopeEnable());
            } else {
                totalCostField.setVisible(1);
            }
            list.add(totalCostField);

            int index = explainList.size();
            for (int i = 0; i < explainList.size(); i++) {
                FieldAttrEntity fieldAttrEntity = explainList.get(i);
                if (Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.UNIT.getAttr())) {
                    index = i + 1;
                    break;
                }
            }
            explainList.addAll(index , list);
            // 剩余天数
            FieldAttrEntity fieldStockSearch = new FieldAttrEntity();
            fieldStockSearch.setAttr(ListOptionEnum.GUARANTEE_SEARCH.getAttr());
            fieldStockSearch.setAttrName(ListOptionEnum.GUARANTEE_SEARCH.getAttrName());
            fieldStockSearch.setFieldType(FieldTypeEnum.TEXT.getType());
            fieldStockSearch.setRedFlag(1);
            fieldStockSearch.setSort(explainList.size());
            fieldStockSearch.setVisible(1);
            fieldStockSearch.setDisableListSort(1);
            explainList.add(explainList.size(),fieldStockSearch);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
            //此处因为是显示，所以要展示所有的回款单类型
            List<ItemPoJo> itemList = dataDictionaryModel.getDictionaryList4PaymentSheetType(true);
            //先移除原类型解释，然后设置后塞入新的
            for (FieldAttrEntity next : explainList) {
                String attr = next.getAttr();
                if (Objects.equals(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), attr)) {
                    next.setItems(itemList);
                    explainMap.put(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), next);
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode())) {
            //此处因为是显示，所以要展示所有的付款单类型
            List<ItemPoJo> itemList = dataDictionaryModel.getDictionaryList4PaySheetType(true);
            //先移除原类型解释，然后设置后塞入新的
            for (FieldAttrEntity next : explainList) {
                String attr = next.getAttr();
                if (Objects.equals(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), attr)) {
                    next.setItems(itemList);
                    explainMap.put(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), next);
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
            //先移除原类型解释，然后设置后塞入新的
            for (FieldAttrEntity next : explainList) {
                String attr = next.getAttr();
                if (Objects.equals(InvoiceDistributorEnum.INVOICE_DATE.getAttr(), attr)) {
                    next.setEditable(BasicConstant.ZERO);
                    break;
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode()) || Objects.equals(businessType,XbbRefTypeEnum.RETURN.getCode())) {
            Boolean isJxcUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
            if (!isJxcUse) {
                explainList.remove(explainMap.get(RefundEnum.REFUND_STATUS.getAttr()));
                explainMap.remove(RefundEnum.REFUND_STATUS.getAttr());
                if (explainMap.containsKey(RefundEnum.PRODUCTS.getAttr())) {
                    FieldAttrEntity productField = explainMap.get(RefundEnum.PRODUCTS.getAttr());
                    Iterator<? extends FieldAttrEntity>  iterator = productField.getSubForm().getItems().iterator();
                    while (iterator.hasNext()) {
                        FieldAttrEntity fieldAttr = JSONObject.parseObject(JSONObject.toJSONString(iterator.next()), FieldAttrEntity.class);
                        if (Objects.equals(fieldAttr.getAttr(), SelectProductEnum.SOURCE_DOC.getAttr())
                                || Objects.equals(fieldAttr.getAttr(), RefundProductEnum.INSTOCK_NUM.getAttr())
                                || Objects.equals(fieldAttr.getAttr(), RefundProductEnum.WAIT_INSTOCK_NUM.getAttr())
                                || Objects.equals(fieldAttr.getAttr(), RefundProductEnum.BATCH.getAttr())
                                || Objects.equals(fieldAttr.getAttr(), RefundProductEnum.GUARANTEE_PERIOD.getAttr())
                                || Objects.equals(fieldAttr.getAttr(), RefundProductEnum.PRODUCE_DATE.getAttr())
                                || Objects.equals(fieldAttr.getAttr(), RefundProductEnum.EXPIRE_DATE.getAttr())
                        ) {
                            iterator.remove();
                        }
                    }
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(businessType,XbbRefTypeEnum.ORDER.getCode())) {
            Boolean isJxcUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
            if (!isJxcUse) {
                explainList.remove(explainMap.get(ContractEnum.SHIP_STATUS.getAttr()));
                explainMap.remove(ContractEnum.SHIP_STATUS.getAttr());
                if (explainMap.containsKey(ContractEnum.PRODUCT.getAttr())) {
                    FieldAttrEntity productField = explainMap.get(ContractEnum.PRODUCT.getAttr());
                    if (Objects.nonNull(productField.getSubForm()) && Objects.nonNull(productField.getSubForm().getItems())) {
                        Iterator iterator = productField.getSubForm().getItems().iterator();
                        while (iterator.hasNext()) {
                            FieldAttrEntity fieldAttr = JSONObject.parseObject(JSONObject.toJSONString(iterator.next()), FieldAttrEntity.class);
                            if ((Objects.equals(fieldAttr.getAttr(), SelectProductEnum.OUTSTOCK_NUM.getAttr()) || Objects.equals(fieldAttr.getAttr(), SelectProductEnum.WAIT_OUTSTOCK_NUM.getAttr()) || Objects.equals(fieldAttr.getAttr(), SelectProductEnum.RETURN_NUM.getAttr()))) {
                                iterator.remove();
                            }
                        }
                    }
                }
            }
        }
        formDataListDTO.setExplainMap(explainMap);
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(formDataListDTO, handlerExplainDTO);
        handlerExplainDTO.setPaasFormEntityExt(form);
        handlerExplainDTO.setExplainList(explainList);
        HandlerExplainVO handlerExplainVO = formDataListFormExplainHandleName.handleExplain(handlerExplainDTO);
        explainList = handlerExplainVO.getHeadList();
        HandleExplainPojo handleExplainPojo = new HandleExplainPojo();
        handleExplainPojo.setExplainList(explainList);
        handleExplainPojo.setFieldList(fieldList);
        handleExplainPojo.setUpdateTime(paasFormExplainEntity.getUpdateTime());
        return handleExplainPojo;
    }

    /**
     * @Author: wujian
     * @Description: 智能补货解释处理
     * @Date: 上午11:06 2022/4/1
     * @Param: []
     * @return: void
     **/
    public void handleSmartReplenishmentExplain(List<FieldAttrEntity> explainList){
        FieldAttrEntity nameAttr = new FieldAttrEntity();
        nameAttr.setAttr(SmartReplenishmentEnum.PRODUCT_NAME.getAttr());
        nameAttr.setAttrName(SmartReplenishmentEnum.PRODUCT_NAME.getAttrName());
        nameAttr.setSaasAttr(SmartReplenishmentEnum.PRODUCT_NAME.getSaasAttr());
        nameAttr.setLinkedType(SmartReplenishmentEnum.PRODUCT_NAME.getLinkedType());
        nameAttr.setFieldType(SmartReplenishmentEnum.PRODUCT_NAME.getFieldType());
        explainList.add(nameAttr);
        FieldAttrEntity noAttr = new FieldAttrEntity();
        noAttr.setAttr(SmartReplenishmentEnum.PRODUCT_NO.getAttr());
        noAttr.setAttrName(SmartReplenishmentEnum.PRODUCT_NO.getAttrName());
        noAttr.setSaasAttr(SmartReplenishmentEnum.PRODUCT_NO.getSaasAttr());
        noAttr.setLinkedType(SmartReplenishmentEnum.PRODUCT_NO.getLinkedType());
        noAttr.setFieldType(SmartReplenishmentEnum.PRODUCT_NO.getFieldType());
        explainList.add(noAttr);
        FieldAttrEntity stockNumAttr = new FieldAttrEntity();
        stockNumAttr.setAttr(SmartReplenishmentEnum.STOCK_NUM.getAttr());
        stockNumAttr.setAttrName(SmartReplenishmentEnum.STOCK_NUM.getAttrName());
        stockNumAttr.setSaasAttr(SmartReplenishmentEnum.STOCK_NUM.getSaasAttr());
        stockNumAttr.setLinkedType(SmartReplenishmentEnum.STOCK_NUM.getLinkedType());
        stockNumAttr.setFieldType(SmartReplenishmentEnum.STOCK_NUM.getFieldType());
        explainList.add(stockNumAttr);
        FieldAttrEntity waitOutAttr = new FieldAttrEntity();
        waitOutAttr.setAttr(SmartReplenishmentEnum.WAIT_OUTSTOCK_NUM.getAttr());
        waitOutAttr.setAttrName(SmartReplenishmentEnum.WAIT_OUTSTOCK_NUM.getAttrName());
        waitOutAttr.setSaasAttr(SmartReplenishmentEnum.WAIT_OUTSTOCK_NUM.getSaasAttr());
        waitOutAttr.setLinkedType(SmartReplenishmentEnum.WAIT_OUTSTOCK_NUM.getLinkedType());
        waitOutAttr.setFieldType(SmartReplenishmentEnum.WAIT_OUTSTOCK_NUM.getFieldType());
        explainList.add(waitOutAttr);
        FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
        fieldAttrEntity.setAttr(SmartReplenishmentEnum.MINI_NUM.getAttr());
        fieldAttrEntity.setAttrName(SmartReplenishmentEnum.MINI_NUM.getAttrName());
        fieldAttrEntity.setSaasAttr(SmartReplenishmentEnum.MINI_NUM.getSaasAttr());
        fieldAttrEntity.setLinkedType(SmartReplenishmentEnum.MINI_NUM.getLinkedType());
        fieldAttrEntity.setFieldType(SmartReplenishmentEnum.MINI_NUM.getFieldType());
        explainList.add(fieldAttrEntity);
    }
    /**
     * 外链列表解释处理
     * @param formDataListDTO
     * @param form
     * @return
     * @throws XbbException
     */
    public HandleExplainPojo handlOuterLinkExplains(FormDataListDTO formDataListDTO, PaasFormEntityExt form) throws XbbException{
        String corpid = formDataListDTO.getCorpid();
        Integer businessType = formDataListDTO.getBusinessType();
        Long formId = form.getId();
        PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            //工单
            WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(workOrderExplainEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            BeanUtil.copyProperties(workOrderExplainEntity, paasFormExplainEntity);
        } else {
            //其他
            paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(paasFormExplainEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        ExplainUtil.filterSpecialAttr(explainList, OuterLinkTypeEnum.SEARCH.getCode(), null);
        List<String> fieldList = new ArrayList<>();
        for (FieldAttrEntity item : explainList) {
            // 外链查询不要汇总
            item.setSummaryFlag(0);
            // 外链查询不要排序
            item.setDisableListSort(1);
            // 外链查询不需要默认值属性，目前是因为公式属性造成值的改动了，所以这边去掉默认值
            item.setDefaultAttr(new DefaultAttrPoJo());
            item.setItems(proFormHelp.setItem(item, form));
            fieldList.add(item.getAttr());
        }
        // 过滤各业务特殊字段
        List<String> attrList = OuterLinkFilterRemoveAttrEnum.getAttrList(businessType);

        OuterLinkConfigEntity permissionSetting = outerLinkConfigService.getOuterLinkConfigEntities(corpid, formId, OuterLinkTypeEnum.SEARCH.getCode(), OutLinkSettingTypeEnum.PERMISSION_SETTING.getCode());
        OuterLinkConfigEntity displaySetting = outerLinkConfigService.getOuterLinkConfigEntities(corpid, formId, OuterLinkTypeEnum.SEARCH.getCode(), OutLinkSettingTypeEnum.DISPLAY_SETTING.getCode());
        // 外链查询处理可见可编辑
        ExplainUtil.handelFieldPermission(explainList, permissionSetting, displaySetting);
        if (Objects.nonNull(displaySetting) && StringUtil.isNotEmpty(displaySetting.getDefaultFormName())) {
            form.setName(displaySetting.getDefaultFormName());
        }

        if (CollectionsUtil.isNotEmpty(attrList)) {
            explainList.removeIf(item -> attrList.contains(item.getAttr()));
        }

        Map<String,FieldAttrEntity> explainMap = paasFormExplainService.getExpalinMap(explainList, paasFormExplainEntity.getBusinessType(), corpid,form.getId());
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())) {
            explainList.remove(explainMap.get(ProductEnum.IS_NOTIFY.getAttr()));
            explainMap.remove(ProductEnum.IS_NOTIFY.getAttr());
            explainList.remove(explainMap.get(ProductEnum.STOCK_NOTIFY.getAttr()));
            explainMap.remove(ProductEnum.STOCK_NOTIFY.getAttr());
        }

        if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
            //此处因为是显示，所以要展示所有的回款单类型
            List<ItemPoJo> itemList = dataDictionaryModel.getDictionaryList4PaymentSheetType(true);
            //先移除原类型解释，然后设置后塞入新的
            for (FieldAttrEntity next : explainList) {
                String attr = next.getAttr();
                if (Objects.equals(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), attr)) {
                    next.setItems(itemList);
                    explainMap.put(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), next);
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode())) {
            //此处因为是显示，所以要展示所有的付款单类型
            List<ItemPoJo> itemList = dataDictionaryModel.getDictionaryList4PaySheetType(true);
            //先移除原类型解释，然后设置后塞入新的
            for (FieldAttrEntity next : explainList) {
                String attr = next.getAttr();
                if (Objects.equals(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), attr)) {
                    next.setItems(itemList);
                    explainMap.put(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), next);
                }
            }
        }
        formDataListDTO.setExplainMap(explainMap);
        HandleExplainPojo handleExplainPojo = new HandleExplainPojo();
        handleExplainPojo.setExplainList(explainList);
        handleExplainPojo.setFieldList(fieldList);
        handleExplainPojo.setUpdateTime(paasFormExplainEntity.getUpdateTime());
        return handleExplainPojo;
    }

    /**
     * 过滤审批中数据
     * @param formDataListDTO
     */
    public void filterApprovalData(FormDataListDTO formDataListDTO) {
        if(Objects.equals(XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(), formDataListDTO.getBusinessType()) || Objects.equals(formDataListDTO.getSubBusinessType(), XbbRefTypeEnum.WARNING_SEARCH.getCode())
            || Objects.equals(XbbRefTypeEnum.ORI_STOCK.getCode(), formDataListDTO.getBusinessType()) || Objects.equals(XbbRefTypeEnum.PREPAY_BALANCE.getCode(),formDataListDTO.getBusinessType())
            || Objects.equals(XbbRefTypeEnum.DISTRIBUTOR_ACCOUNT.getCode(), formDataListDTO.getBusinessType()) || Objects.equals(XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode(), formDataListDTO.getBusinessType())){
            return;
        }
        boolean isDefaultApprovalGroup = Objects.equals(formDataListDTO.getDefaultGroup(), 1) && Objects.equals(formDataListDTO.getListGroupId(), Long.valueOf(ListGroupEnum.APPROVAL.getCode()));
        if (!isDefaultApprovalGroup) {
            ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt(FieldTypeEnum.FLOW_STATUS.getAlias(), "", FieldTypeEnum.FLOW_STATUS.getType(), ConditionEnum.IN.getSymbol(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType()));
            formDataListDTO.getConditions().add(conditionsEntityExt);
        }
    }

    /**
     * 列下拉框元素特殊处理
     *
     * @param formDataListDTO
     * @param formDataListVO
     * @author xingxing.xiao
     * @date 2021/01/29 10:39
     */
    private void specialHandleItem(FormDataListDTO formDataListDTO,PaasFormDataEsListVO formDataListVO) throws XbbException{
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(formDataListDTO.getSubBusinessType());
        switch (redundantTemplateTypeEnum) {
            case CREDIT_TEMPORARY_LIMIT:
                // 过期状态判断
                List<PaasFormDataEntityExt> dataList = formDataListVO.getPaasFormDataESList();
                for (PaasFormDataEntityExt entityExt : dataList) {
                    JSONObject data = entityExt.getData();
                    String temporaryStatus = data.getString(CreditTemporaryLimitEnum.APPLY_STATUS.getAttr());
                    int endTime = data.getIntValue(CreditTemporaryLimitEnum.END_TIME.getAttr());
                    if (endTime < DateTimeUtil.getTodayInt() && !Objects.equals(temporaryStatus, CreditTemporaryApplyStatusEnum.REVOKED.getCode())) {
                        data.put(CreditTemporaryLimitEnum.APPLY_STATUS.getAttr(), CreditTemporaryApplyStatusEnum.EXPIRED.getCode());
                    }
                }
                break;
            default:
                break;
        }
    }

    /**
     * 列表页特殊处理
     *
     * @param formDataListDTO
     * @param formDataListVO
     */
    private void specialHandle(FormDataListDTO formDataListDTO,PaasFormDataEsListVO formDataListVO) throws XbbException{
        List<PaasFormDataEntityExt> formDataList = formDataListVO.getPaasFormDataESList();
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(formDataListDTO.getSubBusinessType());
        switch (redundantTemplateTypeEnum) {
            case COMMUNICATE_PLAN:
                if (formDataList.size() == 0) {
                    break;
                }
                // 查询访客计划执行人，封装到具体数据里去
                Map<Long, String> executorMap = new HashMap<>(formDataList.size());
                List<Long> planIds = new ArrayList<>();
                planIds.add(-1L);
                formDataList.forEach(item -> planIds.add(item.getDataId()));
                Map<String, Object> param = new HashMap<>();
                param.put(StringConstant.CORPID, formDataListDTO.getCorpid());
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("planIdIn", planIds);
                List<CommunicatePlanUserEntity> entitys = communicatePlanUserModel.findEntitys(param);
                for (CommunicatePlanUserEntity entity : entitys) {
                    String name = executorMap.get(entity.getDataId());
                    if (name == null) {
                        executorMap.put(entity.getDataId(), entity.getUserName());
                    } else {
                        executorMap.put(entity.getDataId(), name + "，" + entity.getUserName());
                    }
                }
                for (PaasFormDataEntityExt entity : formDataList) {
                    entity.getData().put(CommunicatePlanEnum.EXECUTOR.getAttr(), executorMap.getOrDefault(entity.getDataId(), ""));
                }
                break;
            case PRODUCT:
            case STOCK_SEARCH:
            case WARNING_SEARCH:
            case GUARANTEE_SEARCH:
                saasListService.setOption(formDataListDTO, formDataListVO);
                break;
            case PAYMENT_TASK:
                if (formDataList.size() == 0) {
                    break;
                }
                // 查询回款计划计划执行人，封装到具体数据里去
                Map<Long, String> executorPaymentTaskMap = new HashMap<>(formDataList.size());
                List<Long> paymentTaskIds = new ArrayList<>();
                paymentTaskIds.add(-1L);
                formDataList.forEach(item -> paymentTaskIds.add(item.getDataId()));
                Map<String, Object> paymentTaskParam = new HashMap<>();
                paymentTaskParam.put(StringConstant.CORPID, formDataListDTO.getCorpid());
                paymentTaskParam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                paymentTaskParam.put("planIdIn", paymentTaskIds);
                List<PaymentTaskUserEntity> paymentTaskUserEntities = paymentTaskUserModel.findEntitys(paymentTaskParam);
                for (PaymentTaskUserEntity paymentTaskUserEntity : paymentTaskUserEntities) {
                    String name = executorPaymentTaskMap.get(paymentTaskUserEntity.getDataId());
                    if (name == null) {
                        executorPaymentTaskMap.put(paymentTaskUserEntity.getDataId(), paymentTaskUserEntity.getUserName());
                    } else {
                        executorPaymentTaskMap.put(paymentTaskUserEntity.getDataId(), name + "，" + paymentTaskUserEntity.getUserName());
                    }
                }
                for (PaasFormDataEntityExt entity : formDataList) {
                    entity.getData().put(PaymentTaskEnum.EXECUTOR.getAttr(), executorPaymentTaskMap.getOrDefault(entity.getDataId(), ""));
                }
                break;
            case CREDIT_LIMIT:
                // 计算有效期内临时额度之和
                creditLimitService.calculateCreditTemporaryLimit(formDataListDTO.getCorpid(), formDataListDTO.getDistributorMark(), formDataListVO);
                break;
            default:
                break;
        }
        if (Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode())) {
            Set<Long> formIdSet = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (PaasFormDataEntityExt paasFormDataEntityExt : formDataListVO.getPaasFormDataESList()) {
                formIdSet.add(paasFormDataEntityExt.getFormId());
            }
            if (formIdSet.size() > 1) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(ParameterConstant.ID_IN, formIdSet);
                param.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
                param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                List<PaasFormEntityExt> formEntityExts = paasFormModel.findEntitys(param);
                Map<Long, PaasFormEntityExt> formEntityExtMap = new HashMap<>(formEntityExts.size());
                formEntityExts.forEach(form -> formEntityExtMap.put(form.getId(), form));
                formDataListDTO.setFormMap(formEntityExtMap);
                param.remove(ParameterConstant.ID_IN);
                param.put("formIdIn", formIdSet);
                List<PaasFormExplainEntity> entityExt = paasFormExplainModel.findEntitys(param);
                Map<Long, List<FieldAttrEntity>> formIdAndHeadListMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                entityExt.forEach(explain-> formIdAndHeadListMap.put(explain.getFormId(), JSONArray.parseArray(explain.getExplains(), FieldAttrEntity.class)));
                formDataListDTO.setFormIdAndHeadListMap(formIdAndHeadListMap);
            }
        }
    }

    /**
     * 处理表单冻结列，隐藏列
     * @param formDataListDTO formDataListDTO
     * @param formDataListVO formDataListVO
     * @throws XbbException xbbException
     * @author 李少杰
     */
    public void setFixedAndInvisible(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO) throws XbbException {
        ColumnSetListDTO columnSetListDTO = new ColumnSetListDTO(formDataListDTO.getCorpid(), formDataListDTO.getAppId(), formDataListDTO.getFormId(), formDataListDTO.getBusinessType(), formDataListDTO.getSubBusinessType(), formDataListDTO.getListGroupId(), formDataListDTO.getUserId());
        userConfigExplainService.setFixedAndInvisible(columnSetListDTO, formDataListVO.getHeadList());

    }

    /**
     * 处理列表页字段排序，兼容只有headList的情况
     * @param formDataListDTO
     * @param headList
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public void explainFieldSort(FormDataListDTO formDataListDTO, List<FieldAttrEntity> headList) throws XbbException{
        PaasFormDataEsListVO formDataListVO = new PaasFormDataEsListVO();
        formDataListVO.setHeadList(headList);
        explainFieldSort(formDataListDTO, formDataListVO);
    }
    /**
     * 处理列表页字段排序
     *
     * @param formDataListDTO
     * @param formDataListVO
     * @throws
     * @author long.rao
     * @date 2019-11-25 14:46
     */
    public void explainFieldSort(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO) throws XbbException{
        ColumnSetListDTO columnSetListDTO = new ColumnSetListDTO(formDataListDTO.getCorpid(), formDataListDTO.getAppId(), formDataListDTO.getFormId(), formDataListDTO.getBusinessType(), formDataListDTO.getSubBusinessType(), formDataListDTO.getListGroupId(), formDataListDTO.getUserId());
        userConfigExplainService.explainFieldSort(columnSetListDTO, formDataListVO.getHeadList());
    }

    /**
     * 处理对账单列表页字段排序
     * @param baseDTO
     * @param title
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public void explainFieldSort4CustomerStatement(BaseDTO baseDTO, List<KeyValuePojo> title) throws XbbException{
        ColumnSetListDTO columnSetListDTO = new ColumnSetListDTO();
        BeanUtil.copyProperties(baseDTO, columnSetListDTO);
        columnSetListDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode());
        columnSetListDTO.setSubBusinessType(XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode());
        ColumnSetListVO columnSetListVO = userConfigService.columnSetList(columnSetListDTO);
        Map<String, Object> userConfigMap = columnSetListVO.getUserConfigMap();
        if (userConfigMap != null) {
            JSONArray fieldSort = (JSONArray) userConfigMap.getOrDefault(UserConfigEnum.COLUMN_SORT_FIELD.getAlias(), new JSONArray());
            JSONArray hideField = (JSONArray) userConfigMap.getOrDefault(UserConfigEnum.COLUMN_INVISIBLE_FIELD.getAlias(), new JSONArray());
            if (Objects.isNull(fieldSort) || fieldSort.isEmpty()) {
                return;
            }
            if (hideField.size() > 0) {
                title.removeIf(item -> hideField.contains(item.getAttr()));
            }
            Map<String, Integer> attrAndSort = new LinkedHashMap<>(fieldSort.size());
            for (int i = 0; i < fieldSort.size(); i++) {
                JSONObject o = (JSONObject)fieldSort.get(i);
                attrAndSort.put(o.getString("attr"), o.getInteger("sort"));
            }
            title.forEach(item-> {
                // 如果attrAndSort里没有，那么证明是新的字段，sort直接给它最大值
                item.setSort(attrAndSort.getOrDefault(item.getAttr(), title.size()));
            });
            title.sort((o1, o2) -> o1.getSort() - o2.getSort());
        }
    }

    /**
     * 每个业务的特殊逻辑
     *
     * @param formDataListDTO
     * @throws XbbException
     * @author long.rao
     * @date 2020-08-24 15:32
     */
    private void formatListCondition(FormDataListDTO formDataListDTO) throws XbbException{
        Integer businessType = formDataListDTO.getBusinessType();
        String corpid = formDataListDTO.getCorpid();
        List<ConditionsEntityExt> conditions = formDataListDTO.getConditions();
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum) {
            case PRODUCT:
                Iterator<ConditionsEntityExt> iterator = conditions.iterator();
                List<ConditionsEntityExt> childConditionList = new ArrayList<>();
                while (iterator.hasNext()){
                    ConditionsEntityExt conditionsEntityExt = iterator.next();
                    String attr = conditionsEntityExt.getAttr();

                    boolean isChildField = ChildProductFieldEnum.isChildField(attr);
                    if (isChildField){
                        //子产品字段
                        if (Objects.equals(attr,ProductEnum.SPECIFICATION.getAttr())){
                            conditionsEntityExt.setAttr(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
                        }
                        childConditionList.add(conditionsEntityExt);
                        iterator.remove();
                    }
                }
                // 规格的常用筛选
                if (!childConditionList.isEmpty()){
                    BoolQueryBuilder boolQueryBuilder = boolQuery();
                    EsUtil.getTermQuery(boolQueryBuilder, formDataListDTO, true);
                    EsUtil.parseCondition(boolQueryBuilder,childConditionList,"",corpid,XbbRefTypeEnum.PRODUCT.getCode());
                    boolQueryBuilder.mustNot(termsQuery(ProductEnum.getAttrConnectData(ProductEnum.PARENT_ID), Collections.singletonList(0)));
                    List<String> childProductFieldList = new ArrayList<>();
                    childProductFieldList.add(StringConstant.DATA_ID);
                    childProductFieldList.add(ProductEnum.getAttrConnectData(ProductEnum.PARENT_ID));
                    List<PaasFormDataEntityExt> childProductList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT,boolQueryBuilder,PaasFormDataEntityExt.class,childProductFieldList);
                    Set<Long> parentIdList = new HashSet<>();
                    parentIdList.add(-1L);
                    for (PaasFormDataEntityExt entityExt : childProductList){
                        parentIdList.add(entityExt.getData().getLong(ProductEnum.PARENT_ID.getAttr()));
                    }
                    conditions.add(new ConditionsEntityExt(FieldTypeEnum.DATAID.getAlias(),"",FieldTypeEnum.DATAID.getType(),ConditionEnum.IN.getSymbol(),new ArrayList<>(parentIdList)));
                }
                conditions.add(new ConditionsEntityExt(ProductEnum.PARENT_ID.getAttr(),"",ProductEnum.PARENT_ID.getFieldType(),ConditionEnum.EQUAL.getSymbol(),Collections.singletonList(0)));
                break;
            case CUSTOMER_COMMUNICATE:
                // 排除项目日志
                conditions.add(new ConditionsEntityExt(FieldTypeEnum.LOG_TYPE.getAlias(),"",FieldTypeEnum.LOG_TYPE.getType(),ConditionEnum.EQUAL.getSymbol(),Collections.singletonList(0)));
                break;
            default:
                break;
        }
        formDataListDTO.setConditions(conditions);
    }

    private void handleSpecial(FormDataListDTO formDataListDTO, WorkOrderDataEsListVO workOrderDataEsListVO, PaasFormDataEsListVO paasFormDataEsListVO) {
        String corpid = formDataListDTO.getCorpid();
        Set<Long> templateIds = new HashSet<>();
        Set<Long> workOrderIdList = new HashSet<>();
        List<WorkOrderEntityExt> workOrderEntityExts = workOrderDataEsListVO.getPaasFormDataESList();
        for (WorkOrderEntityExt workOrderEntityExt : workOrderEntityExts) {
            Long workOrderId = workOrderEntityExt.getId();
            workOrderIdList.add(workOrderId);
            templateIds.add(workOrderEntityExt.getTemplateId());
        }
        Map<Long, WorkOrderTemplateEntity> templateMap = workOrderTemplateModel.getTemplateMap(templateIds, corpid);

        List<PaasFormDataEntityExt> paasFormDataESList = paasFormDataEsListVO.getPaasFormDataESList();
        Map<Long, PaasFormDataEntityExt> paasFormDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            paasFormDataMap.put(paasFormDataEntityExt.getId(), paasFormDataEntityExt);
        }

        //用于存储阶段名称
        Map<Long,String> workOrderStageNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<WorkOrderStageEntity> workOrderStageEntityList = workOrderStageService.getStagesByTemplateIdIn(templateIds, corpid, false);
        for (WorkOrderStageEntity entity : workOrderStageEntityList) {
            workOrderStageNameMap.put(entity.getId(), entity.getName());
        }

        for (WorkOrderEntityExt entity : workOrderEntityExts){
            WorkOrderTemplateEntity workOrderTemplateEntity = templateMap.get(entity.getTemplateId());
            if (Objects.isNull(workOrderTemplateEntity)) {
                LOG.error("工单外链查询获取工单模板出错 dataId = " + entity.getId());
                continue;
            }
            PaasFormDataEntityExt entityExt = paasFormDataMap.get(entity.getId());
            if (Objects.isNull(entityExt)) {
                continue;
            }
            //不限时自由工单
            boolean isLimit = Objects.equals(workOrderTemplateEntity.getIsFree(), 1) && Objects.equals(workOrderTemplateEntity.getExpectedTime(), 0);

            JSONObject orderData = entity.getData();
            JSONObject formData = entityExt.getData();
            //老数据data中没有存阶段状态
            if (orderData.containsKey(WorkOrderEnum.NODE_STATUS.getAttr())){
                formData.put(FieldTypeEnum.WORK_ORDER_NODE_STATUS.getAlias(), WorkOrderNodeStatusEnum.getNameByCode(orderData.getInteger(WorkOrderEnum.NODE_STATUS.getAttr()),""));
            } else {
                formData.put(FieldTypeEnum.WORK_ORDER_NODE_STATUS.getAlias(), "");
            }
            formData.put(FieldTypeEnum.WORK_ORDER_STAGE_NAME.getAlias(),workOrderStageNameMap.getOrDefault(entity.getNowStageId(), ""));
            if (isLimit) {
                //data.put(WorkOrderEnum.TIME_OUT.getAttr(), "");
                TimeConsumingOutPojo timeConsumingOutPojo =  workOrderBasicService.workOrderSpecialConsueTime(entity);
                formData.put(WorkOrderEnum.TIME_OUT.getAttr(), timeConsumingOutPojo.getConsumeTimeStr());
            } else {
                TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderConsueTime(entity);
                formData.put(WorkOrderEnum.TIME_OUT.getAttr(), timeConsumingOutPojo.getConsumeTimeStr());
            }
            if (Objects.equals(formDataListDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                formData.put(FieldTypeEnum.CLOSETIME.getAlias(), entity.getCloseTime());
                formData.put(FieldTypeEnum.ENDTIME.getAlias(), entity.getEndTime());
            } else {
                if (Objects.nonNull(entity.getCloseTime()) && entity.getCloseTime() > 0) {
                    formData.put(FieldTypeEnum.CLOSETIME.getAlias(), DateTimeUtil.getStringEpochSecond(entity.getCloseTime(), DateTimeUtil.SDFYMDHM));
                }
                if (Objects.nonNull(entity.getEndTime()) && entity.getEndTime() > 0) {
                    formData.put(FieldTypeEnum.ENDTIME.getAlias(), DateTimeUtil.getStringEpochSecond(entity.getEndTime(), DateTimeUtil.SDFYMDHM));
                }
            }
            formData.put(FieldTypeEnum.WORK_ORDER_STATUS.getAlias(),WorkOrderNodeStatusEnum.getByCode(entity.getStatus()).getName());
        }
    }

    /**
     * 为阶段停留超时的数据设置超时颜色预警
     *
     * @param formDataListDTO   列表页入参
     * @param formDataListVO    数据列表
     */
    public void setWarningColorData(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataListVO){
       stageHelp.setWarningColorData(formDataListDTO, formDataListVO.getPaasFormDataESList(), formDataListVO.getHeadList());
    }

}
